0

I have narrowed down my error to this specific line (in the check function) using debug50.

// For last char in word
if (trav -> is_word == true)
{
    return true;
}

I am still not sure what the problem is, would appreciate any help!

Check Function

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // Make a new copy of word for changing word to lowercase
    char wordCpy[strlen(word)];
    strcpy(wordCpy, word);

    // Set trav to point to root
    trav = root;
    // Set up index for each char in word
    int trieIndex;

    // Loop over each char in word given, moving through trie
    for (int h = 0; h < strlen(wordCpy); h++)
    {
        // Make word given case-insensitive, using tolower function
        wordCpy[h] = tolower(wordCpy[h]);

        // Use trav pointer to move through respective index
        if (wordCpy[h] == '\'')
        {
            trieIndex = 26;
        }
        else
        {
            trieIndex = wordCpy[h] - 'a';
        }
         // If trav pointer's next path location is NULL, before the last word, word does not exist in trie
        if (trav -> paths[trieIndex] == NULL)
        {
            return false;
        }

        trav = trav -> paths[trieIndex];

        // For last char in word
        if (trav -> is_word == true && h == strlen(wordCpy) - 1)
        {
            return true;
        }
    }
    return false;
}

Here are the other functions just in case...

Load Function

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Create root node for trie
    root = createNode();
    if (root == NULL)
    {
        return false;
    }

    // Create trie index for inserting char from words found in dictionary
    int trieIndex;
    // Create traversal pointer
    trav = root;

    // Open the dictionary file given
    FILE *dictionaryPtr = fopen(dictionary, "r");
    // Check if dictionary file could be opened
    if (dictionaryPtr == NULL)
    {
        return false;
    }

    // Declare character to store each character of dictionary
    char c;
    // Declare an char array in order to store words found, LENGTH + 1 elements
    char word[46];
    memset(&word[0], 0, sizeof(word));

    // Declare a char variable used in the process of adding word to trie
    char charAdd;
    // Declare an index for words found in dictionary
    int index = 0;

    // Loop over words in dictionary, add them to trie
    for (c = fgetc(dictionaryPtr); c != EOF; c = fgetc(dictionaryPtr))
    {
        // If c contains newline character, indicates that new word is on next line
        if (c == '\n')
        {
            // Add word into trie by looping over word
            for (int i = 0; i < strlen(word); i++)
            {
                // Store each char of word into charAdd
                charAdd = word[i];
                // Get number to be added to root array path based on character
                if (charAdd == '\'')
                {
                    // If charAdd is an ', make trieIndex become last element in trie path index
                    trieIndex = 26;
                    // Add charAdd into trie, if charAdd exists, move trav pointer
                    if (trav -> paths[trieIndex] == NULL)
                    {
                        // Create new trie node at that index
                        trav -> paths[trieIndex] = createNode();
                        // If createNode() returned NULL, it has failed
                        if (trav -> paths[trieIndex] == NULL)
                        {
                            return false;
                        }
                        // Move trav pointer to new node
                        trav = trav -> paths[trieIndex];
                    }
                    else
                    {
                        // Move trav to next path
                        trav = trav -> paths[trieIndex];
                    }
                }
                else
                {
                    // Get index value of char based on http://www.asciichart.com/
                    trieIndex = charAdd - 'a';
                    // Add charAdd into trie, if charAdd exists, move trav pointer
                    if (trav -> paths[trieIndex] == NULL)
                    {
                        trav -> paths[trieIndex] = createNode();
                        // If createNode() returned NULL, it has failed
                        if (trav -> paths[trieIndex] == NULL)
                        {
                            return false;
                        }
                        // Move trav pointer to correct index
                        trav = trav -> paths[trieIndex];
                    }
                    else
                    {
                        trav = trav -> paths[trieIndex];
                    }
                }
            }
            // Set index back to 0 for the next word
            index = 0;
            // Set is_word bool in current node to true
            trav -> is_word = true;
            // Increment wordCounter by 1
            wordCounter++;
            // Set trav back to root for next word
            trav = root;
        }
        else
        {
            // Add char c into word array and increment index by 1
            word[index] = c;
            index++;
        }
    }
    // Close dictionary pointer
    fclose(dictionaryPtr);
    loaded = true;
    // Return true if loading is successful
    return true;
}

Unload function

bool unload(void)
{
    freeNode(root);
    return true;
}

void freeNode(trie *temp)
{
    // Use of recursion to free up nodes
    // If all of paths[27] are NULL, free node
    for (int x = 0; x < 27; x++)
    {
        if (temp -> paths[x] != NULL)
        {
            freeNode(temp -> paths[x]);
        }
    }
    free(temp);
}

createNode function

// Function used to create a new node for trie data structure
trie *createNode(void)
{
    trie *node = malloc(sizeof(trie));
    if (node == NULL)
    {
        return NULL;
    }
    // Loop over node trie struct and allocate all pointers in trie to NULL
    for (int x = 0; x < 27; x++)
    {
        node -> paths[x] = NULL;
    }
    // Set is_word in node to false
    node -> is_word = false;
    return node;
}

Trie Node struct

typedef struct trie
{
    // Store current char in dictionary
    bool is_word;
    // 27 Pointers to the next appropriate path
    struct trie *paths[27];
}
trie;

Global Variables

trie *root = NULL;
trie *trav = NULL;
int wordCounter = 0;
bool loaded = false;
1

I'm going to be lazy this time and suggest instead of doing a full depth analysis. Most of the time, when a seg fault occurs and a struct is involved, it suggests a null pointer. In this case, look at the test conditiion:

 if (trav -> is_word == true ...

I would be willing to bet that trav == NULL, so trav->is_word doesn't exist, causing the seg fault. This should be easy enough to check. Try inserting a line like this just before the if statement:

if(trav == NULL) printf("SEG FAULT COMING!\n");

If this isn't the problem, leave a comment and I'll do the deep dive. ;-)

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

1
  • Well, that would be for a new question. If you're posting code, please don't break it up into pieces. Makes it difficult to cut and paste for testing.
    – Cliff B
    May 20 '18 at 8:36

You must log in to answer this question.

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