All tests pass except the valgrind check at the end. I am sure that my unload algorithm isn't correct, but I checked like 5 times, and I can't find logic flaw.
I don't need solution, just a hint what I am doing wrong.
Here is the output of the valgrind (line 65 is line where memory is allocated using calloc):
224 bytes in 1 blocks are still reachable in loss record 1 of 11: (file: dictionary.c, line: 96)
224 bytes in 1 blocks are still reachable in loss record 2 of 11: (file: dictionary.c, line: 65)
224 bytes in 1 blocks are still reachable in loss record 3 of 11: (file: dictionary.c, line: 65)
224 bytes in 1 blocks are still reachable in loss record 4 of 11: (file: dictionary.c, line: 65)
224 bytes in 1 blocks are still reachable in loss record 5 of 11: (file: dictionary.c, line: 65)
224 bytes in 1 blocks are still reachable in loss record 6 of 11: (file: dictionary.c, line: 65)
224 bytes in 1 blocks are still reachable in loss record 7 of 11: (file: dictionary.c, line: 65)
224 bytes in 1 blocks are still reachable in loss record 8 of 11: (file: dictionary.c, line: 65)
224 bytes in 1 blocks are still reachable in loss record 9 of 11: (file: dictionary.c, line: 65)
224 bytes in 1 blocks are still reachable in loss record 10 of 11: (file: dictionary.c, line: 65)
224 bytes in 1 blocks are still reachable in loss record 11 of 11: (file: dictionary.c, line: 65)
Here is the pseudo code:
- call free_node function with node_pointer (node) and incrementer variable (i)
- if node->children[i] is not NULL, go vertically to lower branch
- node_pointer = node.children[i]
- set increment variable to 0 (because we want to start at the 0th node of horizontal level)
- call free_node function with newly set node_pointer and i
- else go horizontally
- free node->children[i]
- increment i by one
- if i is less than number of elements in node.child array (27)
- call function with node_pointer and i
- else
- free node
My intention is to go to the lowest possible node until I hit node with NULL pointers in children array. Then I start going horizontally while node pointers are NULL and I free them. If I encounter not NULL pointer, I go to lower branch and repeat the process.
Here is actual code:
bool free_node(node *nodeArg, int i)
{
if (nodeArg->children[i] != NULL)
{
// traverse vertically
nodeArg = nodeArg->children[i];
i = 0;
free_node(nodeArg, i);
}
else
{
// traverse horizontally
free(nodeArg->children[i]);
i++;
if (i < 27)
free_node(nodeArg, i);
else
free(nodeArg);
}
return true;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
int i = 0;
return free_node(ROOT, i);
}
free
any children directly (they should be freed by the recursively called function), and please do not assign to any parameters. You might remember my opinion from cs50.stackexchange.com/a/30728/12099 ;-)NULL
)?NULL
. What do you think should happen then? You never allocated a memory block atNULL
, so what should be freed? (free(NULL)
will just do nothing)