删除双向链表中的链接

时间:2011-10-15 06:44:54

标签: c linked-list free

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

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

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

2 个答案:

答案 0 :(得分:1)

  

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

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

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

  

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

因为他们需要释放每个current->value(如果他们指向指针......)。

答案 1 :(得分:1)

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

  • 在释放节点之前没有要清理的节点;这通常是一个不正确的假设。
  • 列表的末尾标有NULL指针(即最后一个节点的Next成员是NULL

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

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

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