繁体   English   中英

释放链表的头节点

[英]Freeing the head node of linked list

如果我释放链表的头节点,它只是删除头节点,其他节点仍在内存中,或者它将释放整个列表以及如何?

您的链接列表应该是:

head
+---+    +---+    +---+                               
| 1 |--->| 2 |--->| 3 |---+
+---+    +---+    +---+   |                                
                         null  

head节点仅保留第一个节点的地址,如果您执行free(head) ,它将释放具有值1的第一个节点的内存,而其他节点仍在内存中并且有效访问它们,但是您应该首先保存地址节点2链接访问链表(否则您的代码将发生内存泄漏)。

喜欢:

   new_head = head->next;
   free(head);

一旦取消分配/释放()内存,其未定义行为便无法访问该内存(地址变为无效)。

来自评论:

  1. 是的,您需要一个循环来释放链表中所有节点的内存,执行以下操作:

      while(head){ // while head not null new_head = head->next; // first save address of next free(head); // free first node head = new_head; // set head to next node, not yet free } 
  2. 注释2:
    如果您不删除/释放程序中动态分配的内存,那么它将一直分配给您的进程,直到不终止为止(请记住,在C中,我们没有垃圾收集器)。 动态分配的内存具有生命,直到您的程序不会终止。 因此,如果您已完成分配内存的工作,请明确释放它。

释放头节点只会释放分配给头节点的内存。 其他列表节点将保留。 然后,您必须指向列表的下一个成员。 例如,考虑以下单个链接列表,

A - > B - > C - > D - > Null

在释放头节点A并将头部移动到节点B之后,链接列表将如下所示

B - > C - > D - > Null

释放列表的头节点只释放该节点, 而不是列表的其余部分。

这是数组和链表之间的主要区别 - 内存是分开的。 这是一个例子:

 struct testnode {
      int a;
      int b;
      struct testnode * next;
 };

在数组中,内存可能如下所示:

 struct testnode test[3];

 0x............0000    &test[0] // on a typical computer
 0x............0020    &test[1]
 0x............0040    &test[2]

请注意,数组中的元素是如何彼此紧邻布置的? 释放测试将释放和随后的连续内存,只需要一个调用就可以释放所有内存。

在链表中,内存可能如下所示:

 struct testnode * head;

 // after insertions

 0x............0000    head
 0x............634f    head->next 
 0x............114d    head->next->next

注意内存如何不排序(虽然它可能不总是出来的顺序)。 释放head只会释放head节点,而其余的内存则保持不变。

不,当您释放链表的头节点时,您仅将其使用的内存标记为“可用”。 因此,内存中的其他节点仍将标记为“正在使用中”。

从技术上讲,您仍然可以使用释放的内存,但这是未定义的行为 ,因此不能保证数据(包括指针)仍然可以正确使用。

如果要从内存中删除所有节点,则应递归执行(从next指针的角度来看)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM