【发布时间】:2020-02-11 12:21:10
【问题描述】:
我有一些链表代码,一切正常,直到我在析构函数中创建 pop_front 函数。该代码在其他任何地方都可以使用,我尝试打印链接列表以查看它是否正确创建并且确实如此。这是我的代码中唯一调用 pop_front 的部分,也是我释放任何东西的唯一部分
template <typename T>
class DList {
Node<T>* head;
Node<T>* tail;
public:
DList() {
head = nullptr;
tail = nullptr;
}
void push_front(T newData) {
Node<T>* newNode = new Node<T>(newData, head, nullptr);
if (head) {
head->prev = newNode;
}
else {
tail = newNode;
};
head = newNode;
}
void push_front(DList<T> newList) {
newList.tail->next = head;
head->prev = newList.tail;
head = newList.head;
}
void pop_front() {
if (head) {
Node<T>* pop = head;
head = pop->next;
if (head) {
head->prev = nullptr;
}
else {
tail = nullptr;
}
delete pop;
}
}
~DList() {
while (head) {
pop_front();
}
}
};
【问题讨论】:
-
您没有显示
Node的定义,或者它自己的析构函数的作用。但是我看到您的push_front(DList<T>)方法根本没有考虑空列表,更重要的是,它在将节点链接到目标列表后不会释放其节点的所有权,因此您最终会得到源列表和目标列表尝试在它们都被破坏时释放同一组节点。 -
在某些编译器的调试模式下,释放的内存会被字节
DD覆盖。如果你看到这个地址,那么你几乎肯定是在读取已经在其他地方释放的内存(释放后使用)。您的班级可能没有关注rule of three/five。事实上,尝试复制DList将 导致释放后使用,因为您没有对列表进行值复制。 -
当您看到像 0xDDDDDDDD 这样高度重复的数字时,很有可能计算机正试图告诉您一些事情。在Magic Debug Numbers 的列表中查找它。如果您得到一个看起来很奇怪的十进制数,请将其转换为十六进制,然后查找它。如果你得到的数字大多是重复的,但在最不重要的一端有噪音,你可能有一个添加了偏移量的幻数。假设模式继续并进行查找。
标签: c++ memory-management linked-list