C++课我有这个作业,要实现一个list类,在那里我可以从前面或者后面添加,我已经实现了,但是有个大问题。
collectiontest.cpp
#include "list.hpp"
#include <iostream>
int main(void) {
std::cout << "--- Test List ---" << std::endl;
List<int> l;
std::cout << l;
l.add(2);
l.add_front(3);
l.add(1);
std::cout << l;
std::cout << "remove_front: " << l.remove_front() << std::endl;
std::cout << "remove_front: " << l.remove_front() << std::endl;
l.add(5);
std::cout << l;
std::cout << "Contains 5? " << l.contains(5) << std::endl;
std::cout << "remove_back: " << std::endl;
std::cout << l.remove() << std::endl;
std::cout << "remove_back: " << l.remove() << std::endl;
std::cout << l;
return 0;
}
list.hpp
#pragma once
#include "collection.hpp"
#include "node.hpp"
#include <iostream>
#include <string>
template <typename T>
class List : public Collection<T> {
private:
Node<T>* first;
Node<T>* last;
public:
~List() {
if (first != nullptr) {
}
}
void add_front(T value) {
if (first == nullptr) {
std::cout << "First element front" << std::endl;
Node<T> temp(value, nullptr, nullptr);
first = &temp;
last = &temp;
}
else {
if (first == last) {
std::cout << "First and last are same! front-> " << first << "-" << last << std::endl;
Node<T> temp(value, last, nullptr);
last->previous = &temp;
first = &temp;
std::cout << first << "-" << last << std::endl;
}
else {
Node<T> temp(value, first, nullptr);
first->previous = &temp;
first = &temp;
}
}
}
void add(T value) override {
std::cout << "LOL" << std::endl;
if (first == nullptr) {
std::cout << "First element add" << std::endl;
Node<T> temp(value, nullptr, nullptr);
first = &temp;
last = first;
std::cout << "end of add first item" << std::endl;
}
else {
if (first == last) {
std::cout << "First and last are same! add-> " << first << "-" << last << std::endl;
Node<T> temp(value, nullptr, first);
first->next = &temp;
last = &temp;
}
else {
Node<T> temp(value, nullptr, last);
last->next = &temp;
last = &temp;
}
}
}
T remove_front() {
if (first != nullptr) {
T te = first->content;
Node<T>* temp = first;
first = first->next;
return te;
}
return NULL;
}
T remove() override {
if (last != nullptr) {
Node<T>* temp = last;
T te = last->content;
last = last->previous;
last->next = nullptr;
return te;
}
return NULL;
}
bool isEmpty() override {
return (first == nullptr);
}
bool contains(T value) override {
Node<T>* temp = first;
while (temp != nullptr) {
if (temp->content == value) return true;
temp = temp->next;
}
return false;
}
void clear() override {
Node<T>* temp = first->next;
while (temp != nullptr) {
first = temp;
temp = temp->next;
}
}
int getSize() override {
int counter = 0;
Node<T>* temp = first;
while (temp != nullptr) {
counter++;
temp = temp->next;
}
return counter;
}
Node<int>* getFirst() const {
return first;
}
Node<int>* getLast() const {
return last;
}
friend std::ostream& operator<<(std::ostream& os, const List<int>& l);
};
std::ostream& operator<<(std::ostream& stream, const List<int>& l) {
std::cout << "Output called" << std::endl;
Node<int>* temp = l.getLast();
while (temp != nullptr) {
std::cout << "Schleife betreten" << std::endl;
stream << temp->content << " ";
temp = temp->previous;
}
stream << std::endl;
return stream;
}
collection.hpp
#pragma once
template <typename T>
class Collection {
virtual void add(T value) = 0;
virtual int remove() = 0;
virtual bool isEmpty() = 0;
virtual bool contains(T obj) = 0;
virtual void clear() = 0;
virtual int getSize() = 0;
};
node.hpp
#pragma once
template <typename T>
class Node {
public:
Node<T>* next;
Node<T>* previous;
T content;
Node(T value, Node<T>* next, Node<T>* previous) {
content = value;
this->next = next;
this->previous = previous;
}
~Node() {
}
};
我已经看了好几遍了,但还是得到同样的错误。
我用Visual Studio调试了我的程序,collectortest.cpp
创建了列表,并使用add()
函数添加了第一个值。在调试器中,我看到了如何创建temp
节点,如何将first
设置为temp
的地址,以及如何将last
设置为相同的地址。当我们到达“end of add first item”应该打印到控制台的行时,变量发生了变化,为什么?
您可以在此图像中看到变量如何都具有适当的值:
输出前:
但是,当我离开我设置在“end of add first item”的断点时,会发生这种情况:
输出后:
一定有什么东西我没有看到,因为这完全没有意义。我到处都找过了,也许这只是一些非常愚蠢的东西,但我真的在我的极限这里。
你们谁能帮忙解释一下问题出在哪里吗?
我试图执行我的程序并适当地创建节点,但是在内存中出现了一个奇怪的错误。
1条答案
按热度按时间axr492tv1#
来自@Wyck:
你正在使用一个指针指向在堆栈上分配的东西,当它超出作用域时,无论你是否注意到它曾经所在的地址,它都将被销毁/无效。
来自@user4581301:
是您越来越不希望使用
new
的时候之一。来自@TedLyngmo:
对于@Wyck提到的问题,需要使用
new
/delete
动态分配和释放内存。这些是作为问题的注解发布的答案。我的
Node
总是因为超出范围而被销毁。我需要使用new
,这样它们就可以存储在堆中,并且在超出范围时不会自动销毁。编辑:我不能选择我自己的答案是正确的2天,所以这个问题可悲的是保持开放。