【问题标题】:Delete a linked list where the delete is after the recursive call c++ [duplicate]删除递归调用c ++之后删除的链表[重复]
【发布时间】:2019-09-02 05:30:16
【问题描述】:

在我的一生中,我无法弄清楚如何使用递归删除整个链表,其中删除发生在递归调用之后。我试过这个:

void remove_nodes(node * &head)
{
     if (!head)
         return;
     remove_nodes(head->next);
     delete head;
} 

节点结构很简单:

struct node
{
      int data;
      node * next;
 };

当我使用上面的函数然后显示列表时,它仍然存在,但有垃圾数据。我不明白我做错了什么。

【问题讨论】:

  • 可能没有错。显示的代码看起来不错。不要在delete 之后显示,因为结果将是未定义的。有时你会得到东西,有时你不会。这几乎是平局的运气。
  • 谢谢!是的,显然我的系统允许我访问垃圾。
  • 大多数系统都允许访问垃圾。这可能是一个以速度为名的重大问题。在访问指针之前检查它是否有效是昂贵的或不可能的,并且没有有效的程序会这样做,因此任何检查都会对正确编写的程序造成性能损失。对于那些无效的程序......好吧,你自己一个人。幸运的是,有像 asan 和 valgrind 这样的工具可以帮助您追踪这些傻瓜。
  • 啊,我明白了,这是有道理的。谢谢!我一定会研究这些程序。我对此很陌生,因此非常感谢您的指导!
  • 一种思路是:分配内存的时候,拿一块地,说:“这是我的地,不许其他人在这里建”,然后就可以了无论那块土地(例如推土机并建造新房子)。然后,当您释放(删除)该内存时,您将出售该契约并允许其他人获取它。这并不意味着其他任何人必须来推平你的房子并立即建造新房子 - 这只是意味着他们可以。只要没有其他人抢占那块土地,你的房子就会在那里——但不要回去,因为它随时都可能被推平。

标签: c++


【解决方案1】:

您永远不会清除“下一个”指针 - 您只会删除它。您的 remove_nodes 函数可能希望如下所示:

void remove_nodes(node * &head)
{
     if (!head)
         return;
     remove_nodes(head->next);
     delete head;
     head = nullptr;
}

delete head 没有将 head 设置为 nullptr;如果您的显示函数正在检查一个真实的指针以确定是否显示它只是要跳华尔兹进入已删除的对象。

【讨论】:

  • 赞成这一点,因为通过使指针为空,这个答案解决了未来的问题:“我想删除列表的末尾而不是整个列表。”
  • 这太完美了!非常感谢!这就是我得到垃圾数据的原因。我对递归完全陌生,所以什么时候应该 NULL 什么时候没有必要让我感到困惑。再次感谢您!
  • @Psych 大多数时候您不需要为空,因为您将永远不会再次使用该变量。如果您怀疑自己会这样做,您可以将代码设为 null 或重写代码,这样您就永远不会这样做了。在这种情况下,您至少需要将一个 head 置空,因为您必须对列表进行空终止才能使 if (!head) 之类的东西起作用。
猜你喜欢
  • 2017-08-22
  • 2021-12-20
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多