Good afternoon
Hitting the last hurdle with unloading memory, can't figure where I'm going wrong
Code to load the hash table:
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// Initialize hash table
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)
{
node *new_node = malloc(sizeof(node));
if (new_node == NULL) // if malloc did not work
{
unload();
return false;
}
else
{
strcpy(new_node->word, word);
int first_letter_number = hash(word);
// insert new_node at beginning of linked list
new_node->next = hashtable[first_letter_number];
hashtable[first_letter_number] = new_node;
dict_word_count++;
}
}
// Close dictionary
fclose(file);
// Indicate success
return true;
}
unload:
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
int nodes_freed = 0;
int elements_freed = 0;
// free the nodes
for (int i = 0; i < N; i++)
{
for (node *ptr = hashtable[i]; ptr != NULL; ptr = ptr->next)
{
free(ptr);
nodes_freed++;
}
}
// free the hash table
for (int i = 0; i < N; i++)
{
if (hashtable[i])
{
free(hashtable[i]);
elements_freed = 0;
}
}
printf("Number of nodes freed: %i\n", nodes_freed);
printf("Number of hashtable elements freed: %i\n", elements_freed);
return true;
}
My thinking for the unload is first to free all the nodes within the linked lists for each letter a..z
Then free each element in the array hashtable
Number of words in the dictionary is 143,091 and the number of nodes being freed is this exact number per printf above (number of hashtable elements freed is 0 so looks like they're all being cleared when freeing the nodes)
Valgrind log:
==9232== Memcheck, a memory error detector
==9232== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9232== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9232== Command: ./speller ./texts/lalaland.txt
==9232== Parent PID: 187
==9232==
==9232== Invalid read of size 8
==9232== at 0x401244: unload (dictionary.c:130)
==9232== by 0x400E49: main (speller.c:153)
==9232== Address 0x534b6a0 is 48 bytes inside a block of size 56 free'd
==9232== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232== by 0x40123F: unload (dictionary.c:132)
==9232== by 0x400E49: main (speller.c:153)
==9232== Block was alloc'd at
==9232== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232== by 0x40115E: load (dictionary.c:56)
==9232== by 0x4009A4: main (speller.c:41)
==9232==
==9232== Invalid free() / delete / delete[] / realloc()
==9232== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232== by 0x40129B: unload (dictionary.c:141)
==9232== by 0x400E49: main (speller.c:153)
==9232== Address 0x534b670 is 0 bytes inside a block of size 56 free'd
==9232== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232== by 0x40123F: unload (dictionary.c:132)
==9232== by 0x400E49: main (speller.c:153)
==9232== Block was alloc'd at
==9232== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9232== by 0x40115E: load (dictionary.c:56)
==9232== by 0x4009A4: main (speller.c:41)
==9232==
==9232==
==9232== HEAP SUMMARY:
==9232== in use at exit: 0 bytes in 0 blocks
==9232== total heap usage: 143,096 allocs, 143,122 frees, 8,023,416 bytes allocated
==9232==
==9232== All heap blocks were freed -- no leaks are possible
==9232==
==9232== For counts of detected and suppressed errors, rerun with: -v
==9232== ERROR SUMMARY: 143117 errors from 2 contexts (suppressed: 0 from 0)
Any ideas?