【发布时间】:2019-05-15 12:51:41
【问题描述】:
我使用结构编写了一个单链表实现。它不是管理列表操作的外部类的一部分。相反,所有操作都直接由节点处理。
我知道,如果结构定义是类的一部分,比如 ListManager,则在 ListManager 实例上调用析构函数只需要遍历类管理的链表并删除每个节点。
然而,由于这个链表不是外部类的一部分,它自己管理所有的操作,我对如何编写析构函数有点困惑。
版本 1 运行良好,它是一个遍历列表并释放与每个节点关联的内存的递归调用。
版本 2 导致了无限循环。我不明白为什么,因为这是我为管理节点链表的容器类实现析构函数的一种方式。
版本 3 运行良好,但过于冗长。
我使用 valgrind 和 python 导师运行了所有三个版本来检查泄漏和其他问题。
任何帮助解释为什么版本 2 不起作用以及为什么以这种方式实现析构函数是不正确的,我们不胜感激!
结构链表
#include <iostream>
#include <string>
using namespace std;
struct Node
{
int id;
Node* next;
Node(int newId = 0, Node* newNext = NULL)
: id(newId), next(newNext) { }
};
析构函数版本 1
~Node()
{
if (next != NULL)
delete next;
}
析构函数第 2 版
~Node()
{
Node* lead = this;
Node* follow = this;
while (follow != NULL)
{
lead = lead->next;
delete follow;
follow = lead;
}
}
析构函数版本 3
~Node()
{
Node* lead = this;
Node* follow = this;
if (follow != NULL)
{
lead = lead->next;
delete follow;
follow = lead;
}
}
主要
int main()
{
Node* head = NULL;
head = new Node(23, head);
head = new Node(54, head);
head = new Node(81, head);
head = new Node(92, head);
delete head;
return 0;
}
【问题讨论】:
-
您通常应该有一个
LinkedList类来管理它。Node的上下文太少,无法自行清除所有内容(它无法选择是清除所有内容还是只清除一个节点并重新链接列表的其余部分)。 -
尝试1可以简化为
delete next;,删除空指针即可 -
将递归与循环结合通常不好。
-
所有版本实际上都是递归的。第 1 版和第 3 版实际上是等价的——尽管第 3 版通过分配额外的变量来混淆它。在版本 2 中,
delete follow再次递归调用析构函数,该析构函数执行类似的循环,这也是递归的......因此它会尝试多次删除特定对象,这会导致未定义的行为。 -
@Peter no,版本 3 也是
delete this
标签: c++ linked-list destructor singly-linked-list