Search code examples
cpointersfree

Free() Function in C of pointer to struct not compiling


I have implemented a linkedlist, and I am trying to create a function that starts at the head of the linkedlist and essentially stores the pointer to the struct in curr. It then uses free()...unfortunetly I keep getting

LinkedList_Header(27343,0x1000dedc0) malloc: *** error for object 0x1007b42c0: pointer being freed was not allocated

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

struct node* initialize(int input){
    struct node* head = (struct node*)malloc(sizeof(struct node));
    head->data = input;
    head->next = NULL;
    return head;
}

void freeing(struct node* head){
    struct node* curr = head;
    while(curr->next != NULL){
        free(curr);
    }
    free(curr);
}

Solution

  • The issue with your code is the freeing function, which is incorrect. There are two possible ways for the function to fail.

    Double Free

    1. If the head of the linked list has a valid pointer on the next pointer, the freeing function will keep looping on the same initial pointer, which is the head. That will create a double free, thus you're freeing an unallocated pointer.
    //Would loop forever if it wasn't because of the double free.
    //The loop never continues into the next pointer, and stays on the head.
    struct node* curr = head;
    while(curr->next != NULL){
         free(curr);
    }
    

    Never integrates through the linked list.

    1. The second issue with your code is that the while loop will always iterate on the head, if it wasn't because of the double free, the loop would iterate forever.

    The solution to issue 1 and 2 is to make the while loop iterate through the linked list correctly.

    void freeing(struct node* head){
        struct node* curr = head;
        struct node* next;
        while(curr != NULL){
            next = curr->next;
            free(curr);
            curr = next;
        }
    }
    

    The whole code with test:

    #include <stdio.h>
    #include <stdlib.h>
    
    struct node {
        int data;
        struct node* next;
    };
    
    struct node* initialize(int input){
        struct node* head = (struct node*)malloc(sizeof(struct node));
        head->data = input;
        head->next = NULL;
        return head;
    }
    
    void freeing(struct node* head){
        struct node* curr = head;
        struct node* next;
        while(curr != NULL){
            next = curr->next;
            printf("Freeing: %d\n", curr->data);
            free(curr);
            curr = next;
        }
    }
    
    int main()
    {
        struct node* a = initialize(23);
        a->next = initialize(42);
        freeing(a);
    }
    

    This is the output, now the code avoids double free and iterates correctly.

    Freeing: 23
    Freeing: 42