【问题标题】:Freeing the head node of linked list释放链表的头节点
【发布时间】:2013-07-23 11:09:53
【问题描述】:

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

【问题讨论】:

    标签: c memory linked-list malloc


    【解决方案1】:

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

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

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

    B -> C -> D -> 空

    【讨论】:

      【解决方案2】:

      你的链表应该是这样的:

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

      head节点只保留第一个节点的地址,如果你这样做free(head),那么它将释放第一个节点的内存,值为1only,其他节点仍在内存中并且访问它们是有效的,但是您应该首先保存节点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 中我们没有垃圾收集器)。 动态分配的内存在您的程序没有终止之前一直存在。因此,如果您已使用分配的内存完成工作,请明确释放它。

      【讨论】:

      • 所以使用循环并逐个删除节点是我唯一的选择,或者有什么方法可以一次性删除列表。
      • @System_Coder 好的,您正在寻找删除完整列表,是的,您需要一个循环来释放所有节点的内存
      • Grijesh Chauhan 在评论中 Dinesh 说如果我调用 free(head) 那么整个链接列表将被删除。
      • 我理解的是逐个节点删除,如果我只删除头节点而不在纯C程序中存储下一个地址,系统将如何响应。
      • @System_Coder 然后保持节点将消耗内存,直到您的代码不终止
      【解决方案3】:

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

      这是数组和链表的主要区别——内存是分开的。 这是一个插图:

       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 节点,其余的内存保持不变。

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-10-30
          • 2019-08-18
          • 2011-09-19
          • 1970-01-01
          • 1970-01-01
          • 2018-06-03
          • 2018-05-17
          相关资源
          最近更新 更多