简体   繁体   中英

Free Linked-List In C

Hi I need help freeing my Linked List in C. When I run this code I get a seg fault 11. Everything up to the freeing works perfectly. Thank you for your help!

#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);
}

The original code has a few issues:

1) The while(next != NULL) loop tries to use already freed node.

2) The loop already takes care of the releasing root ( next = root; ) so there is no need to release root separately.

3) In order for while loop to work properly the tail / head of the list has to be properly NULL terminated. (I have added that termination in the first for loop)

4) Second loop is supposed to print all x values. It did not. The counter was short by one number.

The improved variation of the program is presented below. Please check the program output as well.

#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;
}

Output:

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

释放节点的循环检查next调用free(next)是否为NULL

As already stated by the other answer, the free() below is in the wrong place, as it frees the memory that is then checked in the condition of the while loop.

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

However also, if move the first statement of that block to the end of the block as you suggested in your comment, your problem is probably the fact that this loop itself is fully sufficient to free the entire list, and so the statement free(root) AFTER the loop is likely a double free, which is usually an error. You can delete it.

There are couple of issues in your code which are listed bellow and the most important one is number 1.

  1. The pointer next in first item of your list (root) does not point to NULL , because it will be changed on the first for loop. So while(next != NULL) will not work because there is no item in your linked list which points to NULL .
  2. malloc will return pointer with type void * , so it is better to cast it to your next .
  3. After doing memory allocation, the result should be checked, if the memory was allocated successfully or not. Also, I would suggest you to use typedef for defining your linked list.

Your code should be like this:

#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;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM