I'm trying to free a linked list which is made up a list struct and multiple node stucts. Each node struct has a string attached to it.
My thought process is that if I start at the head and cycle through to the tail of a given list, and I free the string in each node and then the node. After every string and node is freed, then I free the list itself.
I need to free the string as I am mallocing the size of the string in another function earlier in my program.
My function is:
void releaseTB (TB tb){
if(tb != NULL){
if(tb->head != NULL){
Node curr = tb->head;
Node prev = NULL;
while(curr != NULL && curr != tb->tail->next){
prev = curr;
curr = curr->next;
free(prev->line);
free(prev);
}
}
free(tb);
}
}
The condition curr != tb->tail->next
in the while loop is dealing when I only want to free a sublist with in a greater list.
In case it is off relevance at all, these are my structs:
typedef struct textbuffer *TB;
typedef struct node *Node;
struct textbuffer{
Node head;
Node tail;
};
struct node{
Node prev;
Node next;
char *line;
};
I get the correct output when running my program, but I am getting an Invalid read of size 8. The valgrind output is:
==7705== Memcheck, a memory error detector
==7705== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7705== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==7705== Command: ./dry5
==7705==
Original Tb:
1.1 abc
1.2 def
xxxxx
==7705== Invalid read of size 8
==7705== at 0x400ADC: releaseTB (textbuffer.c:124)
==7705== by 0x4013EF: deleteTB (textbuffer.c:355)
==7705== by 0x4007FA: main (dry5.c:14)
==7705== Address 0x51e0208 is 8 bytes inside a block of size 32 free'd
==7705== at 0x4C29E90: free (vg_replace_malloc.c:473)
==7705== by 0x400ACC: releaseTB (textbuffer.c:128)
==7705== by 0x4013EF: deleteTB (textbuffer.c:355)
==7705== by 0x4007FA: main (dry5.c:14)
==7705==
First and second line are deleted...
xxxxx
Released Tb
==7705==
==7705== HEAP SUMMARY:
==7705== in use at exit: 0 bytes in 0 blocks
==7705== total heap usage: 11 allocs, 11 frees, 219 bytes allocated
==7705==
==7705== All heap blocks were freed -- no leaks are possible
==7705==
==7705== For counts of detected and suppressed errors, rerun with: -v
==7705== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
where: releaseTB (textbuffer.c:124)
is while(curr != NULL && curr != tb->tail->next){
and 0x400ACC: releaseTB (textbuffer.c:128)
is free(prev);
.
Any help would be greatly appreciated. If any further clarification is needed, I'll do my best to explain it.
Where is
tb->tail
pointing before you start the loop?If it is NULL,
tb->tail->next
is wrong.If it is not NULL, and is pointing to a node in the list, it is still wrong by the time you freed all the nodes.