在C中释放链表结构时的困惑

时间:2012-05-14 18:52:55

标签: c memory-leaks linked-list malloc free

我在链接列表结构中以两种free()'malloc()'内存方式玩杂耍。假设我使用以下C代码创建单链表;

#include<stdio.h>
#include<stdlib.h>

struct node_type{
  int data;
  struct node_type *next;
  struct node_type *prev;
}
typedef struct node_type node; 
typedef struct node_type *list; 

void main(void){
  list head,node1,tail;
  head=(list)malloc(sizeof(node));
  tail=(list)malloc(sizeof(node));
  node1=(list)malloc(sizeof(node));
  head->next=node1;tail->prev=node1;
  node1->prev=head;node1->next=tail;node1->data=1;

  /*Method-1 for memory de-allocation*/
  free(head->next->next);
  free(head->next);
  free(head);

  /*OR*/

  /*Method-2 for memory de-allocation*/
  free(tail);
  free(node1);
  free(head);

  /*OR*/

  /*Method-3 for memory de-allocation*/
  free(node1);
  free(tail);
  free(head); 
}

现在,我有以下问题:

Q1)上面代码中显示的三种内存解除分配方法中的哪一种是正确/不正确的。

Q2)是否有必要按照方法1和2中使用的free()内存中的任何顺序进行内存解除分配或随机free()内存也没问题?

3 个答案:

答案 0 :(得分:2)

您展示的所有方法都是正确的,只有当指向已分配内存的指针在另一个已分配的内存中 时才应遵循特定的顺序,如果先释放容器,则会丢失它

例如,对于分配:

int ** ipp;
ipp = malloc(sizeof(int*));
*ipp = malloc(sizeof(int));

正确的free订单将是:

free(*ipp);
free(ipp);

free(ipp);
free(*ipp); // *ipp is already invalid

答案 1 :(得分:1)

所有这些方法都运行良好。您可以按照您喜欢的顺序释放malloc分配的内存块。

想象一下,释放它时,你分配内存的顺序必须颠倒过来。如果是这样的话,你永远不能在列表中间插入或删除项目。您唯一可用的动态分配数据结构将是下推式堆栈。

答案 2 :(得分:1)

这是一个从头开始释放链表的简单方法。 (注意,如果你在列表的末尾,这假设“next”将为NULL。)

node * it = head;
while( NULL != it ) {
  node * tmp = it;
  it = it->next;
  free(tmp);
}