Search code examples
cpointerslinked-listfreesingly-linked-list

what does this error means : "free(): double free detected in tcache 2"


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

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

typedef struct node node_t;


void print_list(node_t *head) {
    node_t *temp = head;

    while(temp -> next != NULL) {
        printf("%d -> ", temp->value);
        temp = temp->next;
    }
    printf("%d ", temp->value);
    printf("\n");
}

node_t* create_new_node(int value) {
    node_t *temp;
    temp = malloc(sizeof(node_t));
    temp -> value = value;

    return temp;
}

void insert_after_node(node_t *tmp, node_t *newnode) {
    newnode -> next = tmp -> next;
    tmp -> next = newnode;
}

node_t* find_node(int num, node_t* head) {
    node_t *tmp = head;
    while(tmp != NULL) {
        if(tmp -> value == num)return tmp;
        tmp = tmp -> next;
    }

    return NULL;
}

node_t* delete_head(node_t* head) {
    node_t* temp = head;
    head = head -> next;
    free(temp);

    return head;
}

void free_list(node_t* head) {
    node_t* temp = head;
    while(head != NULL) {
        free(temp);
        temp = head;
        head = head -> next;
    }
}

int main(){
    node_t *head = NULL;
    node_t *temp = NULL;
    for(int i = 0; i < 10; i++) {
        temp = create_new_node(i);
        temp -> next = head;
        head = temp;
    }

    print_list(head);
    insert_after_node(
        find_node(8, head),
        create_new_node(13));
    print_list(head);

    head = delete_head(head);
    print_list(head);


    free_list(head);
    return 0;
}

output:

9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 
9 -> 8 -> 13 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 
8 -> 13 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 
free(): double free detected in tcache 2
Aborted (core dumped)

I was trying to implement basic operations of linked list using C. It has some basic functions such as creating new node using malloc, printing list, inserting node after a particular node, freeing the whole list using free. But got the error. Can anybody give me some insight of what this error might mean.


Solution

  • Within the function free_list

    void free_list(node_t* head) {
        node_t* temp = head;
        while(head != NULL) {
            free(temp);
            temp = head;
            head = head -> next;
        }
    }
    

    you are deleting the memory pointed to by the pointer to the head node twice. In the first iteration of the loop you are deleting the memory pointed to by the pointer to the head node

        node_t* temp = head;
        while(head != NULL) {
            free(temp);
            //...
    

    and in the second iteration of the loop you are doing the same due to this assignment

    temp = head;
    

    Moreover this statement

    head = head -> next;
    

    invokes undefined behavior because there is used a pointer to the already freed memory.

    The function should be defined at least the following way

    void free_list(node_t* head) {
        while(head != NULL) {
            node_t* temp = head;
            head = head -> next;
            free(temp);
        }
    }
    

    Though it would be better to define the function like

    void free_list(node_t **head) {
        while( *head != NULL ) {
            node_t* temp = *head;
            *head = ( *head ) -> next;
            free(temp);
        }
    }
    

    And the function is called like

    free_list( &head );
    

    In this case after calling the function the pointer head in main will be equal to NULL.