Home > Back-end >  Linkedlist | free(): double free detected in tcache 2 Aborted (core dumped)
Linkedlist | free(): double free detected in tcache 2 Aborted (core dumped)

Time:07-01

I hope someone can help me with this issue. I'm always getting the error free(): double free detected in tcache 2 Aborted (core dumped) when i try to free the allocated memory of the three nodes.

The code works when i free ìter and only one of the two nodes head or new, but using valgrind shows that there are Heap-leaks and that only 2 allocated memories from 3 were freed. Any advices?

#include <stdlib.h>
#include "linkedlist.h"
#include <string.h>

//adding a new node before the head node
node* add_front(node *head, node *new_node){
        new_node -> next = head;
        head = new_node;
        return head;
}

int main(){
    node *head = malloc(sizeof(node));
    strcpy(head -> name, "A");
    head -> next = NULL;
    
    node *new_node = malloc(sizeof(node));
    strcpy(new_node -> name, "B");
    head = add_front(head, new_node);
    
    node *iter = head;

//printing all nodes
    while(iter != NULL){
        printf("%s -> ", iter->name);
        iter = iter -> next;
    }
    free(iter);
    free(new_node);
    free(head);

    return 0;
}
-------------------------------------
//linkedlist.h
typedef struct node_t{
    char name[100];
    struct node_t *next;
}node;
  
node* add_front(node* head, node *new_node);
-------------------------------------
//valgrind error

==13290== Memcheck, a memory error detector
==13290== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13290== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==13290== Command: ./linked
==13290== 
B -> A -> ==13290== 
==13290== HEAP SUMMARY:
==13290==     in use at exit: 112 bytes in 1 blocks
==13290==   total heap usage: 3 allocs, 2 frees, 1,248 bytes allocated
==13290== 
==13290== 112 bytes in 1 blocks are definitely lost in loss record 1 of 1
==13290==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==13290==    by 0x1091C8: main (linkedlist.c:13)
==13290== 
==13290== LEAK SUMMARY:
==13290==    definitely lost: 112 bytes in 1 blocks
==13290==    indirectly lost: 0 bytes in 0 blocks
==13290==      possibly lost: 0 bytes in 0 blocks
==13290==    still reachable: 0 bytes in 0 blocks
==13290==         suppressed: 0 bytes in 0 blocks
==13290== 
==13290== For lists of detected and suppressed errors, rerun with: -s
==13290== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

CodePudding user response:

head = add_front(head, new); moved *new to *head so

    free(new);
    free(head);

frees the same pointer. And since you move *iter to the next the free(iter) will be called on a null.

If you want to free the full tree I suggest you do it in the while loop.

   node *curr = null;
   while(iter != NULL){
        printf("%s -> ", iter->name);
        curr = iter;
        iter = iter -> next;
        free(curr);
    }

CodePudding user response:

iter is a pointer to your node when you free the node it points to, you free iter by default.

if I were you, I would write a function to free the whole list as follows:

/*function to free a list*/
void free_list(node **head){
    node * tmp;
    while(*head!= NULL){
        tmp=*head;
        *head=(*head)->next;
        free(tmp);
    }
    return;

}
  •  Tags:  
  • c
  • Related