我使用一个struct编写了一个单链接列表实现。它不是管理列表上的操作的外部类的一部分。相反,所有的操作都由节点直接处理。
我理解,如果struct定义是类的一部分,比方说ListManager,那么调用ListManager实例上的析构函数只需要迭代由类管理的链接列表并删除每个节点。
但是,由于这个链接列表不是外部类的一部分,并且管理所有操作本身,所以我对如何编写析构函数感到有点困惑。
版本1运行良好,它是一个递归调用,遍历列表,释放与每个节点相关的内存。
版本2导致无限循环。我不明白为什么,因为这是我为管理Node链接列表的容器类实现析构函数的一种方法。
第3版运行良好,但过于冗长。
我运行了这三个版本,使用val差生和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;
}发布于 2018-12-14 09:15:33
在第2版中,您已经编写了一个循环,通过循环遍历列表并删除每个元素,从而在一个析构函数调用中清除整个列表。但是,所发生的并不是只有一个析构函数调用。每次删除元素时,都会再次调用析构函数。
因此,最后,对于第一次调用,delete follow转换为delete this (因为follow = this;)。这将导致再次调用第一个节点的析构函数,从而导致无穷无尽的循环。
下面的节点将被多次销毁,导致未定义的行为,但由于无限循环,它甚至没有到达那里。
发布于 2018-12-14 09:38:12
您只需要每个Node删除(最多)另一个Node,最终删除所有节点。重新分配本地指针不会影响列表的结构。
2和3都是delete this,在最好的时候是可疑的,再加上一些无关的仪式,在破坏者中。它们都是未定义的行为,删除同一对象(至少)两次。
你的第一次尝试已经接近了。
不要将自己与指针值的复制混淆在一起,只需使用拥有的指针类型,比如std::unique_ptr。
struct Node
{
int id;
std::unique_ptr<Node> next;
Node(int id = 0, std::unique_ptr<Node> next = {})
: id(id), next(std::move(next)) { }
// correct destructor is implicit
};https://stackoverflow.com/questions/53776528
复制相似问题