C中的自由链接列表

时间:2016-10-03 00:02:02

标签: c linked-list free

您好我需要帮助释放我在C中的链接列表。当我运行此代码时,我得到了一个段错误11.一切直到解放都能完美地运行。谢谢你的帮助!

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

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

int main(void){
    struct node *root, *next;

    root = malloc(sizeof(struct node));
    root -> x = 0;
    root -> next = NULL;

    next = root;

    for (int i = 0; i <=10; i++){
        next -> next = malloc(sizeof(struct node));
        next -> x = i;
        next = next -> next;
    }

    next = root;

    for (int j = 0; j <= 10; j ++){
        printf("%i", next -> x);
        next = next -> next;
    }
        next = root;

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

4 个答案:

答案 0 :(得分:1)

原始代码有一些问题:

1)while(next != NULL)循环尝试使用已释放的节点。

2)循环已经处理了释放rootnext = root;),因此无需单独释放root

3)为了使while循环正常工作,列表的tail / head必须正确NULL终止。 (我在第一个for循环中添加了终止)

4)第二个循环应该打印所有x值。它没。柜台短了一个数字。

该计划的改进变化如下。请检查程序输出。

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

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

int main(void){
    struct node *root, *next, *to_free;

    root = malloc(sizeof(struct node));                   // 1 malloc

    root->x = 777;
    root->next = NULL;

    printf("allocating memory for root. root->x = %i\n\n", root-> x);

    next = root; // next points to "head" (root)

    for (int i = 0; i <= 10; i++){
        next->next = malloc(sizeof(struct node));      // 11 mallocs

        printf("allocating memory for next. next->x = %i\n", i+1 );   

        next->next->x = i+1;                           //

        next = next->next;
        next->next = NULL;                             // list termination is needed!
    }
    printf("\n");

    next = root; // next points to "head" (root)

    for (int j = 0; j <= 11; j ++){                   // 12 nodes has to be printed! 
        printf("Printing x = %i\n", next->x);
        next = next->next;
    }
    printf("\n");

    next = root;   //  next points to "head" (root)

    while(next != NULL)         
    {   
        to_free = next;         // we will free `next` as `to_free` soon

        next = next->next;      // move to the next node   

        printf("deallocating node with x = %i\n", to_free->x);

       free(to_free);          // now free the remembered `next`
    }
 return 0;
}

输出:

allocating memory for root. root->x = 777

allocating memory for next. next->x = 1
allocating memory for next. next->x = 2
allocating memory for next. next->x = 3
allocating memory for next. next->x = 4
allocating memory for next. next->x = 5
allocating memory for next. next->x = 6
allocating memory for next. next->x = 7
allocating memory for next. next->x = 8
allocating memory for next. next->x = 9
allocating memory for next. next->x = 10
allocating memory for next. next->x = 11

Printing x = 777
Printing x = 1
Printing x = 2
Printing x = 3
Printing x = 4
Printing x = 5
Printing x = 6
Printing x = 7
Printing x = 8
Printing x = 9
Printing x = 10
Printing x = 11

deallocating node with x = 777
deallocating node with x = 1
deallocating node with x = 2
deallocating node with x = 3
deallocating node with x = 4
deallocating node with x = 5
deallocating node with x = 6
deallocating node with x = 7
deallocating node with x = 8
deallocating node with x = 9
deallocating node with x = 10
deallocating node with x = 11

答案 1 :(得分:0)

释放节点的循环检查{/ 1}} next 后是否调用了NULL

答案 2 :(得分:0)

正如另一个答案已经说明的那样,下面的free()位于错误的位置,因为它释放了在while循环条件下检查的内存。

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

但是,如果您按照评论中的建议将该块的第一个语句移动到块的末尾,那么您的问题可能就是这个循环本身完全足以释放整个列表,因此声明free(root)循环之后可能是双重释放,这通常是一个错误。你可以删除它。

答案 3 :(得分:0)

下面列出了代码中的几个问题,其中最重要的是数字1。

  1. 列表(根)的第一项中的指针next不会指向NULL,因为它将在第一个for循环中更改。因此,while(next != NULL)将不起作用,因为您的链接列表中没有指向NULL的项目。
  2. malloc将返回类型为void *的指针,因此最好将其强制转换为您的next
  3. 进行内存分配后,应检查结果是否成功分配了内存。 另外,我建议您使用typedef来定义链接列表。

您的代码应如下所示:

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

typedef struct node{
    int x;
    struct node *next, *temp;
} node_t;

int main(int argc, char *argv[]){
  node_t *root, *next, *temp;

  root = (node_t *) malloc(sizeof(node_t));
  if(root == NULL){
    /* Do somthing */
    fprintf(stderr, "unable to allocate memory\n");
    exit(1);
  }
  root -> x = 100;
  root -> next = NULL;
  for (int i = 0; i <= 10; i++){
    next = (node_t *) malloc(sizeof(node_t));
    if(next == NULL){
      /* Do somthing */
      fprintf(stderr, "unable to allocate memory\n");
      exit(1);
    }
    next -> x = i;
    next -> next = root;
    root = next;
  }
  temp = next;
  while(temp != NULL){
    printf("x value is: %d\n", temp -> x);
    temp = temp -> next;
  }

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