gpt4 book ai didi

c++ - 这个单向链表析构函数是如何导致死循环的?

转载 作者:行者123 更新时间:2023-11-30 01:35:38 24 4
gpt4 key购买 nike

我使用结构体编写了一个单向链表实现。它不是管理列表操作的外部类的一部分。相反,所有操作都直接由节点处理。

我知道如果结构定义是类的一部分,比如 ListManager,调用 ListManager 实例上的析构函数只需要一个遍历类管理的链表并删除每个节点。

但是,由于这个链表不是外部类的一部分并且它自己管理所有操作,所以我对如何编写析构函数感到有点困惑。

版本 1 运行良好,它是一个遍历列表并释放与每个节点关联的内存的递归调用。

版本 2 导致无限循环。我不明白为什么,因为这是我为管理 Node 链表的容器类实现析构函数的一种方式。

版本 3 运行良好但过于冗长。

我使用 valgrind 和 python tutor 运行了所有三个版本,以检查是否存在泄漏和其他问题。

感谢任何帮助解释为什么版本 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;
}

最佳答案

在版本 2 中,您编写了一个循环,通过遍历列表并删除每个元素,在一次析构函数调用中清除整个列表。然而,发生的事情并不是你只有一个析构函数调用。每次删除元素时,都会再次调用析构函数。

所以最后,对于第一次调用,delete follow 转换为 delete this(因为 follow = this;)。这会导致再次调用第一个节点的析构函数,从而导致死循环。

以下节点将被多次销毁,导致未定义的行为,但由于无限循环,它甚至没有到达那里。

关于c++ - 这个单向链表析构函数是如何导致死循环的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53776528/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com