C:如何释放链表中的节点?

23 c linked-list heap-memory

如何释放在另一个函数中分配的节点?

struct node {
    int data;
    struct node* next;
};

struct node* buildList()
{
    struct node* head = NULL;
    struct node* second = NULL;
    struct node* third = NULL;

    head = malloc(sizeof(struct node));
    second = malloc(sizeof(struct node));
    third = malloc(sizeof(struct node));

    head->data = 1;
    head->next = second;

    second->data = 2;
    second->next = third;

    third->data = 3;
    third->next = NULL;

    return head;
}  
Run Code Online (Sandbox Code Playgroud)

我在main()中调用了buildList函数

int main()
{
    struct node* h = buildList();
    printf("The second element is %d\n", h->next->data);
    return 0;
}  
Run Code Online (Sandbox Code Playgroud)

我想释放头,第二和第三变量.
谢谢.

更新:

int main()
{
    struct node* h = buildList();
    printf("The element is %d\n", h->next->data);  //prints 2
    //free(h->next->next);
    //free(h->next);
    free(h);

   // struct node* h1 = buildList();
    printf("The element is %d\n", h->next->data);  //print 2 ?? why?
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

两个打印2.不应该免费调用(h)删除h.如果是这样的话,为什么h-> next->数据可用,如果h是免费的.当然,'第二'节点没有被释放.但是由于头部被移除,它应该能够引用下一个元素.这里的错误是什么?

ins*_*ity 54

一个迭代函数来释放你的列表:

void freeList(struct node* head)
{
   struct node* tmp;

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

}
Run Code Online (Sandbox Code Playgroud)

该功能的作用如下:

  1. 检查if是否head为NULL,如果是,则列表为空,我们只返回

  2. 保存headtmp变量中,并head指向列表中的下一个节点(这是在head = head->next

  3. 现在我们可以安全地free(tmp)变量,head只需指向列表的其余部分,返回步骤1

  • @foobar如果节点中的数据也是使用malloc创建的,我们是否必须在释放temp之前释放它?像:免费(tmp->数据);免费(tmp); (4认同)
  • @Robert确切地说!如果先释放'tmp`,那么tmp-> data可能会指向垃圾,你会得到一个seg错误. (3认同)
  • 只需确保将列表头指针传递给此函数后将其设置为 null。事实上,在释放节点之前将每个节点的每个下一个指针设置为空也是一个好主意。 (2认同)

elc*_*uco 5

只需遍历列表:

struct node *n = head;
while(n){
   struct node *n1 = n;
   n = n->next;
   free(n1);
}
Run Code Online (Sandbox Code Playgroud)