0

I've been working on speller, and all my code does the job fine but I can't get rid of the memory leak valgrind is giving me.

It seems to be something to do with my load function. I think it's my new_node which is declared in the while loop - so I can't free it. Every time I try to declare it outside of the loop or free it in any manner I either get memory errors stopping the program from running, or the program runs but just freezes up before MISSPELLED WORDS.

Can anyone help?! Here is my load function:

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// Initialize hash table - Makes sure each index is null
for (int i = 0; i < N; i++)
{
    hashtable[i] = NULL;
}

// Open dictionary
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
    unload();
    return false;
}

// Buffer for a word
char word[LENGTH + 1];

// Insert words into hash table
while (fscanf(file, "%s", word) != EOF)
{

    //Malloc new node
    node *new_node = malloc(sizeof(node));

    //Make sure new_node isn't null
    if (new_node == NULL)
    {
        unload();
        free(new_node);
        free(hashtable);
        return false;
    }

    //Copies word to new node
    strcpy(new_node->word, word);

    //Creates a hash table index based on the word
    int Index = hash(new_node->word);

    //If there isn't a linked list at the index already
    if (hashtable[Index] == NULL)
    {
        new_node->next = NULL;
        hashtable[Index] = new_node;
        WordCount++;
    }

    //if there is already a linked list at the index
    else
    {
        new_node->next = hashtable[Index];
        hashtable[Index] = new_node;
        //printf("Word %s added at existing index %i\n", new_node->word, Index);
        WordCount++;
    }

}

// Close dictionary
fclose(file);

// Indicate successa
return true;

And here is my unload function:

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
    node *cursor = hashtable[i];
    while (cursor != NULL)
    {
        node *temp = cursor;
        cursor = cursor->next;
        free(temp);
    }
    free(cursor);

    if (cursor == NULL)
    {
        return true;
    }

}
return false;
}

When I run valgrind --leak-check=full --show-leak-kinds=all ./speller texts/cat.txt I get this:

==24554== 
==24554== HEAP SUMMARY:
==24554==     in use at exit: 7,501,928 bytes in 133,963 blocks
==24554==   total heap usage: 143,093 allocs, 9,130 frees, 8,014,232 bytes allocated
==24554== 
==24554== 7,501,928 bytes in 133,963 blocks are still reachable in loss record 1 of 1
==24554==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24554==    by 0x42253D: load (dictionary.c:60)
==24554==    by 0x420962: main (speller.c:40)
==24554== 
==24554== LEAK SUMMARY:
==24554==    definitely lost: 0 bytes in 0 blocks
==24554==    indirectly lost: 0 bytes in 0 blocks
==24554==      possibly lost: 0 bytes in 0 blocks
==24554==    still reachable: 7,501,928 bytes in 133,963 blocks
==24554==         suppressed: 0 bytes in 0 blocks
==24554== 
==24554== For counts of detected and suppressed errors, rerun with: -v
==24554== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

1 Answer 1

1

Have a look at your unload. You are returning true the first time the cursor is null. So your loop doesn't end up checking all of the table.

Don't return true until the very end.

1
  • Had another look and your advice fixed it - thank you!
    – user23081
    Feb 1, 2019 at 15:21

You must log in to answer this question.

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