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