I saw a similar question about memory leaks with speller "pset5 valgrind memory leaks", but that poster found a solution that doesn't seem to work at all for my program. Just like that user, I get about twice as many allocs in valgrind as the number of entries in the dictionary, as well as twice the number of frees shown.

They solved this by changing part of their struct definition to char*. Here's my struct definition and related variables:

//list structure
typedef struct node
    char word[LENGTH + 1];
    struct node* next;

node* hashtable[hsize];
node* new_node;
node* cursor;

It seems that if I change the declaration of word within my struct I get a seg fault (if changed to char*) or "incompatible pointer types" if I change it to char* word[LENGTH + 1].

Here's my unload function:

[hidden behind edit flag]

So, my question is: how is my struct definition related to this inefficiency in unload? It seems, because of the numbers(2x as many allocs as dictionary entries and as frees) like free is only freeing part of each node and malloc is being called for each struct component separately. Is this possible?

Here's my load function:

[hidden behind edit flag]

and the valgrind output:

==3069==     in use at exit: 6,510,908 bytes in 125,204 blocks
==3069==   total heap usage: 268,297 allocs, 143,093 frees, 13,952,044 bytes                
==3069==   Allocated
==3069== 6,510,556 bytes in 125,203 blocks are definitely lost in loss  

==3069==    at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-   
==3069==    by 0x8049087: check (dictionary.c:59)
==3069==    by 0x8048B6D: main (speller.c:117)
==3069== LEAK SUMMARY:
==3069==    definitely lost: 6,510,556 bytes in 125,203 blocks
==3069==    indirectly lost: 0 bytes in 0 blocks
==3069==      possibly lost: 0 bytes in 0 blocks
==3069==    still reachable: 352 bytes in 1 blocks
  • allocs don't just happen. If you're getting twice as many allocs as you have words, it's because you're mallocing them. What type of leaks do you have? What does valgrind say about the blocks? are they "still reachable", "definitely lost"? – Irene Sep 13 '15 at 18:56
  • If you're getting twice as many allocs as words, I'm more interested in seeing your load function. The first thing I want to see is if you do something like node* tmp = malloc(something); followed by a reassignment to tmp like tmp = node->next; This is a very common error in this exercise - creating a pointer and initializing with a malloc or calloc call and then reassigning the pointer to something else, thus losing the originally malloc'd memory. In this case, it should have been initialized to NULL instead of malloc'd. – Cliff B Sep 13 '15 at 19:57
  • So, the leak summary is now shown above. It's almost entirely "definitely lost." Again, what catches my eye is the allocs/frees ratio in the heap summary (roughly 2:1). I did think it had more to do with my load function than with unload, though I don't use any temp pointers. And I'm wondering how the poster of a similar question's solution of simply changing the struct definition relates to reducing most of the leaks. – Warrenwa5 Sep 13 '15 at 21:53

Your valgrind results:

==3069==    at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-   
==3069==    by 0x8049087: check (dictionary.c:59)
==3069==    by 0x8048B6D: main (speller.c:117)

show that you are mallocing nodes in check. Your check function should not be mallocing any nodes. It should simply be looking through your hashtable nodes to find the words.

  • You were correct. I couldn't figure how check was related - even though it was implicated by valgrind, because I was mallocing a cursor outside of any loop, which I thought was innocuous and necessary. I removed the malloc and now the bulk of my memory leak is gone. So, because I malloced a cursor variable and used the cursor to search for a word, every time it was re-assigned via cursor = cursor -> next malloc was called again, is that right? Do you never malloc a temp node used for searching (or any other purpose)? – Warrenwa5 Sep 13 '15 at 22:27
  • The cursor is simply a pointer to a node. It doesn't require you to create space for an entire node (which is what malloc does). – curiouskiwi Sep 13 '15 at 22:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .