释放链表的头节点

时间:2013-07-24 05:50:49

标签: c memory linked-list malloc

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

4 个答案:

答案 0 :(得分:5)

您的链接列表应该是:

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

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

喜欢:

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

一旦你释放/释放()一个内存,它的未定义行为就不能访问(地址变得无效)。

来自评论:

  1. 是的,你需要为链表中的所有节点提供一个循环到free()内存,做这样的事情:

     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中我们没有垃圾收集器)。 动态分配的内存具有生命,直到您的程序不会终止。因此,如果您已完成分配内存的工作,请明确释放它。

答案 1 :(得分:1)

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

A - > B - > C - > D - >空

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

B - > C - > D - >空

答案 2 :(得分:1)

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

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

 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节点,而其他内存不会受到影响。

答案 3 :(得分:0)

不,当你释放链表的头节点时,你只标记它用作“免费使用”的内存。因此,内存中的其他节点仍将标记为“正在使用中”。

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

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