1

so I've been battling through the fifth pset and this is where I can not find a proper way to continue.

When I try to run it, it always aborts and gives this error: * Error in `./speller': double free or corruption (!prev): 0x0000000002526ca0 *

Code of the function (I am using a trie as a data structure):

bool unload(void)
{
    current = root;
    unloadreal(current);
    return true;
}

bool unloadreal(node *node)
{
    for (int i = 0; i < 27; i++)
    {
        if (current->children[i] != NULL)
        {
            current = current->children[i];
            unloadreal(current);
        }
    }
    free(current);
    return true;
}
1

The problem lies in these two lines:

        current = current->children[i];
        unloadreal(current);

Think about what happens after the recursive calls start to return. current is no longer at the parent level, but at the last child in the chain. In the last call to unloadreal(), current will be freed and will return one level back. When it gets there, it will again try to free the same value of current, causing your double free. This will also disrupt the for loop cycling through the same level 27 times. Instead, each time it finds a child, it will drop down 1 level in the current recursion instead of in the next call. (It's a long explanation, but you can map it out on paper. )

The correct way to recursively call in this scenario is:

        unloadreal(current->children[i]);

This will preserve the correct value of current throughout the recursive calls. No guarantees that there aren't other issues.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

3
  • Thank you for the advice Cliff. I am playing with it right now and I've done some changes to my code. To me, it should be running smoothly now, yet it does not. Valgrind reports 0 errors and 0 mem leaks. Somehow the program thinks that even though I've freed all the nodes up to and including the root one, the root pointer is still not NULL. Could you please help me a bit? Here is the code: i.imgur.com/A3Xzq3o.png. – Martin Wzatek May 15 '16 at 12:26
  • Actually I believe it works in a way that after I free a pointer, the dynamic memory is dismissed, but the pointer is not set to NULL. Instead it is now pointing to some junk data in memory, so I can not use if(root == NULL) to verify whether the bool unload returns true or false, is that right? What should I do then, set every node freed to NULL and then set the root to NULL as well or is there another way around it? – Martin Wzatek May 15 '16 at 12:43
  • Your belief is correct. When you free memory, it is released, but the pointer will not be set to null. The pointer will continue to contain the same address that it had before, but it is simply no longer valid. If you want it to be null, you need to set it to null, but there's no need to do so in the children. When they're freed, they will disappear anyways. Since root is a named var, you may want to null it, but since root will not be used again, there's no need. The program is about to end anyways. The important thing is that all the malloc'd memory is freed before the program ends. – Cliff B May 15 '16 at 16:24

You must log in to answer this question.

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