【问题标题】:Deleting links in a doubly linked list删除双向链表中的链接
【发布时间】:2011-10-15 06:44:53
【问题描述】:

我正在用 C 语言编写一个基于双向链表的代码。我错误地认为通过执行 free(head_node) 来删除头节点。随着运行的进行,我可以看到计算机速度变慢(这显然是由于内存泄漏)。我搜索了 stackoverflow 和其他网站,我通常遇到的删除链接列表的代码是这样的:

Node* current = head;
while( current != NULL ) {
Node* next = current->Next;
free( current );
current = next;
}

当我在我的代码中尝试这个时,程序只是在 free 语句之后挂起,而没有返回调用这个函数的函数。上面的代码是否与双向链表相关?我的列表成员数据也包含很多指针。当我在其中一个链接上释放时,它是否释放了成员指向的所有数据?请使用代码 sn-ps 或参考书籍提出建议和澄清。 谢谢。

【问题讨论】:

    标签: c linked-list free


    【解决方案1】:

    当我在其中一个链接上释放时,它会释放成员指向的所有数据吗?

    没有。如果您在垃圾收集语言中删除了对对象的最后一个引用,就会发生这种情况,但 C 不能那样工作。您需要手动释放已分配的每一位内存。

    该代码看起来像您通常用于单链表或双链表的代码,假设它的值都不是指针。

    我的列表成员数据也包含很多指针。

    因为它们是你需要释放每个 current->value 以及(如果它们是指向指针的指针......)。

    【讨论】:

    • 我刚刚发现我的列表节点除了 next 和 prev 元素之外还有另外两个指向数据的指针。我现在试着释放他们两个。 free(current->data1); free(current->data2); free(current) 。我的代码仍然挂起。有输入吗?
    • @PrapanchNair:啊。未能free() 可能不会导致您的计算机挂起。您使用的代码看起来是正确的,所以我倾向于认为您的链表构造不正确。
    • data2,作为我的链表节点成员的指针数据是另一个单链表。
    • 电脑没有死机,只是程序死机了,好像在无限循环运行。
    • @PrapanchNair:对不起,我理解你,但写错了。
    【解决方案2】:

    您发布的代码应该适用于单链表或双链表,但做了一些假设:

    • 在释放节点之前无需清理节点;这通常是一个错误的假设。
    • 链表末尾标有NULL指针(即最后一个节点的Next成员为NULL

    关于第一个假设: 由于您在节点中动态分配了数据,并且假设您在其他地方没有另一个指向它的指针,您稍后将使用它来清理它,因此您需要在释放每个节点之前释放该数据。在 C 中,这不是为您完成的;一般规则是,如果您必须自己分配它,您也必须自己释放它。处理这个问题的一个明智的方法是编写一个函数来清理和释放一个节点,并调用它而不是仅仅调用free();你的清理函数仍然会释放节点,但它会首先释放节点的数据。

    关于第二个假设: 将最后一个节点的 Next 指针设置为 NULL 以标记结束是一种非常常见的做法,因为这样可以很容易地判断您何时已遍历列表。对于双向链表,first 节点的Prev 指针也是如此。但是,如果它是一个循环列表,则最后一个节点只是指向第一个节点——这会破坏您发布的代码。在这种情况下,您将从节点head->Next 而不是head 开始,并检查current 是否不是head 而不是NULL。然后在最后处理head,因为您最初跳过了它。

    还有一件事: 确保在完成释放列表后,不要让 head 指向无效(已释放)节点,然后再次尝试访问列表...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-16
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多