0

I am using a trie data structure for speller. I used a recursive function to unload the memory, so I could backtrack up the data structure after removing the last of the arrays of all null pointers . However, it returns a segmentation fault and I, for the past 2 days, can't seem to get my head around why.

Here is my code for the unload function:

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    // call an unload function that can take in a pointer input
    return liberator(root);
}

bool liberator(tnode* ucursor)
{
    // iterate over each element in the array
    for (int p = 0; p < 26; p++)
    {
        // check whether one of or both of the two adjacent pointers in the array are not NULL
        if ((ucursor->children[p] != NULL && ucursor->children[p + 1] == NULL) || (ucursor->children[p] == NULL && ucursor->children[p + 1] != NULL) || (ucursor->children[p] != NULL && ucursor->children[p + 1] != NULL))
        {
            // if not NULL, call function on the pointer[p]
            liberator(ucursor->children[p]);
        }

        // if pointer[25] is NULL but pointer[26] is not
        if (p == 25 && ucursor->children[p] == NULL && ucursor->children[p + 1] != NULL)
        {
            // call function on pointer[26]
            liberator(ucursor->children[p + 1]);
        }

        // if 25th pointer is NULL & the 26th (last pointer) is NULL
        if (p == 25 && ucursor->children[p + 1] == NULL)
        {
            // free that whole array of pointers
            free(ucursor);
        }
    }

    return true;
}

If the if statement is too long, it just checks if two adjacent pointers are not NULL. If, for example, any one of or both of the 0th pointer and the 1st pointer are not NULL, then the liberator function is called on the 0th pointer, and so on for the rest of the pointers in the array. And if p is 25, the 25th pointer is NULL, and the 26th pointer is not NULL, then the liberator function is called on the 26th pointer. If all pointers in the array become NULL, then that array is freed.

The error is as follows:

dictionary.c:180:23: runtime error: member access within null pointer of type 'tnode' (aka 'struct trienode')
Segmentation fault

The line causing the error is 180, which is the same as the first if statement nested inside the for loop.

I tried running gdb and debug50, but still failed to understand what's causing this issue. My guess is that I'm trying to access a member within an array that has already been freed. But according to my interpretation of the code I wrote, I'm only freeing until I'm at the end of the array. And I only reach the end of the array when all previous elements in the array are NULL pointers.

2
  • You got an answer on your reddit post: reddit.com/r/cs50/comments/8dujy3/…
    – curiouskiwi
    Apr 22 '18 at 21:14
  • Hi Raffay. Now that you have an answer elsewhere, could you please answer this question yourself and accept it? Otherwise, it'll stay in the unanswered question pool forever. thanks. ;-)
    – Cliff B
    Apr 23 '18 at 0:13
0

The problem was actually with the first if statement. Specifically with this part:

... || (ucursor->children[p] == NULL && ucursor->children[p + 1] != NULL) || ...

Because of this line, I was essentially checking if the p'th child was NULL, and if it was, I was trying to access that p'th child, which was causing the "member access within null pointer" error. The problem was rectified with a simple for loop iterating over each element and an if statement that checked for children that were not null, and called the recursive function on the not null child.

You must log in to answer this question.

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