【问题标题】:Linked list destructor that loops forever?永远循环的链表析构函数?
【发布时间】:2018-07-22 04:43:39
【问题描述】:

所以我正在制作一个链接列表,除了列表的析构函数之外,它的所有内容都按照我的意愿工作:

PhoneList::~PhoneList()
{
    PhoneNode *ptr = head;

    while (ptr != NULL)
    {
        head = head->getNext();
        delete ptr;
        ptr = head;
    }
}

当程序运行时,它会做我需要它做的所有其他事情,但是当它试图调用它并结束程序时,它似乎在析构函数上无限循环。这是我在这里的第一个问题,而且我对整个编程有点陌生,所以如果你需要查看我的更多程序代码来理解这个析构函数,我很乐意分享!

【问题讨论】:

  • 它看起来还不错,尽管 IMO 的混乱程度略低:while (head) {PhoneNode* to_remove = head; head = head->getNext(); delete to_remove;}。我认为您的错误除了带有格式错误列表的 dtor 之外的其他地方。仔细检查您的插入和删除功能。如果您发布这些插入和删除功能的一些代码,有些人可能会发现问题。无限循环很可能是由于列表节点未正确链接造成的。
  • 我觉得它也应该有用。而且我也有同样的想法,但是将这段代码从析构函数中取出并留空就完全解决了这个问题。我觉得它必须是析构函数,因为它成功调用并执行了所有其他代码,直到它到达 main() 的末尾。我认为调试器也刚刚证实了这种怀疑,因为当我在它所在的程序部分中断时,它告诉我程序处于析构函数的 while 循环中。
  • 我也很欣赏循环建议!喜欢看到让我的代码更干净的方法:)
  • 留空可能会避免无限循环遍历列表,但问题很可能是由于列表格式错误。其他列表操作成功并不意味着它们使列表完好无损。例如,下一个指针之一可能指向垃圾内存,此时析构函数中的循环可能会无限循环。尝试分享一些用于插入和删除列表节点的代码——我认为我们应该能够发现其中任何一个问题。
  • 你这傻鹅!!! :-D 完整程序中的析构函数有一个分号:while (ptr != NULL); 如果列表非空,这将导致无限循环。您没有在原始 sn-p 中包含分号(这很好)。

标签: c++ linked-list destructor dynamic-memory-allocation


【解决方案1】:

最好为PhoneNode 添加一个析构函数,这样每个都删除它的后继者。那么你根本不需要循环:

PhoneNode::~PhoneNode()
{
    delete next;
}

请注意,这会遍历整个剩余列表。

那么你的 PhoneList 析构函数看起来像:

PhoneList::~PhoneList()
{
    delete head;
}

注意在您的Delete(int id) 方法中,如果您将要删除的节点位于列表中间(即它还不是零),则将其归零。否则,您将丢失列表的其余部分。

【讨论】:

  • 好点!没有那样看。但我仍然对它为什么不起作用感到好奇,因为我一直在努力追踪代码,而一切似乎都可以正常工作。请原谅我的无知,但我不太明白在删除列表中间的节点的“下一个”指针之前如何将其清零会做任何不同的事情......我的代码不是删除节点并设置'前一个节点的下一个'等于删除节点的'下一个'?基本上跳过它然后释放内存?
  • 事实上,不会将要删除的指针的“下一个”归零实际上会导致删除它之后的所有内容,因为我将前一个节点的“下一个”设置为等于任何值被删除节点的“下一个”指向?然后前一个节点会指向空,忘记删除节点之后的所有内容?我真的很好奇,因为我认为我已经完美地工作了
  • 你必须小心使用这样的递归析构函数。如果列表很大,可能会导致堆栈溢出错误,因为每个析构函数调用都会将一个参数(this 指针)压入调用堆栈。使用迭代循环更安全。
  • @phillyb 你必须(a)保存next(b)设置next = NULL;(c)处理next的保存值。
猜你喜欢
  • 2020-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
  • 2016-09-30
相关资源
最近更新 更多