Search code examples
c++dictionarytrie

Why does some words give segmentation fault? While others seem to work fine


Making a dictionary using a trie in C++. Gives segmentation fault on some inputs.

Debugging helped me find that the problem was in the check function. Specifically after it exits the loop, at the check isword condition.

typedef struct node
{
    bool is_word;
    struct node *children[27];
} node;

node *createNode()
{
    // Void -> Node*
    // Create a pointer to a node(structure)
    // Allocate memory and store address in child pointer
    node *child = (node *)malloc(sizeof(node));
    // Initialize each node in child to NULL
    for (int i = 0; i < N; i++)
    {
        child->children[i] = NULL;
    }
    // Initialize the is_word variable
    child->is_word = false;
    // Return the pointer
    return child;
}

bool check(const char *word)
{
    int i = 0;

    // Create a pointer to the root of the trie
    node *ptr = root;

    // Iterate over each letter
    while (word[i] != '\0')
    {
        char c = tolower(word[i]);

        // Get the key for each letter
        int key = hash(c);

        // If the node at the key is null then word is misspelled
        if (!ptr)
        {
            return false;
        }
        else
        {
            ptr = ptr->children[key];
            i++;
        }
    }

    // Check if isword at the last letter is true
    if (ptr->is_word)
    {
        return true;
    }
    else
    {
        return false;
    }
}

error when input some words

I expect the output to be FOUND or NOT FOUND, but actual output is a segmentation fault error.


Solution

  • You need to check that ptr is not null, since it will be if you reach the end of the string and it's not a word in your trie.
    You can also condense the code a bit.

    bool check(const char *word)
    {
        const node * ptr = root;
        for (int i = 0; ptr != nullptr && word[i] != '\0'; i++)
        {
            ptr = ptr->children[hash(tolower(word[i]))];
        }
        return ptr != nullptr && ptr->is_word;
    }