Search code examples
c++dictionarytrie

C++ dictionary trie implementation


I am getting a segfault in my insert function on the line:

current->isWord = true;

Everything compiles fine with no warnings or errors (g++ -Wall -Wextra). My main function just calls the insert function once and it won't work. Here is my code; it is a hybrid between my .h and .cpp file:

const int alphabetSize = 26;

struct Node
{
    bool isWord;
    Node* child[alphabetSize];
};

Dictionary::Dictionary()
{
    initNode(head); //Node* head; is defined in my .h file under private:
}

bool Dictionary::isPrefix(string s)
{
    Node* current = endOfString(s, false);
    if (current == NULL)
    {
        return false;
    }
    else
    {
        return true;
    }
}

bool Dictionary::isWord(string s)
{
    Node* current = endOfString(s, false);
    if (current == NULL)
    {
        return false;
    }
    else
    {
        return current->isWord;
    }
}

void Dictionary::insert(string s)
{
    Node* current = endOfString(s, true);
    current->isWord = true; //segfault here
}

//initializes a new Node
void Dictionary::initNode(Node* current)
{
    current = new Node;
    current->isWord = false;
    for (int i = 0; i < alphabetSize; i++)
    {
       current->child[i] = NULL;
    }
}

//returns a pointer to the Node of the last character in the string
//isInsert tells it whether it needs to initialize new Nodes
Node* Dictionary::endOfString(string s, bool isInsert)
{
    Node* current = head;
    Node* next = head;
    for (unsigned int i = 0; i < s.length(); i++)
    {
        if (isalpha(s[i]) == true)
        {
            int letter = (tolower(s[i]) - 'a');
            next = current->child[letter];
            if (next == NULL)
            {
                if (isInsert == false)
                {
                    return NULL;
                }

                initNode(next);
                current->child[letter] = next;
            }
            current = current->child[letter];
        }
    }

    return current;
}

Solution

  • initNode creates a new Node and initializes it, but it is then discarded. Because current is passed by value, when it is modified inside of the function, the changes do not propagate outside of initNode. The straightforward fix is to make it pass by reference:

    void Dictionary::initNode(Node*& current)