1

I get a segmentation fault whenever I run the program with the large dictionary, but not the small one, so I guess the error lies somewhere in load or unload but I can't localize it. The program also seems to run fine when using gdb, and I don't know if gdb ignores memory issues or whatever, but the program never crashes in gdb, only when I run it normally. I also included parts of dictionary.h that's relevant to understanding the code below. I've been stuck for hours and I even rewrote my code a few times trying to approach it from different angles, but to no luck. check is intentionally not completed since I want to fix these issues before I continue.

dictionary.c

[code removed to comply to academic honesty]

/**
 * Loads dictionary into memory.  Returns true if successful else false.
 */
bool load(const char* dictionary)
{
    // load dictionary
    FILE* fp = fopen(dictionary, "r");
    if (fp == NULL)
    {
        printf("Couldn't open %s.\n", dictionary);
        return false;
    }

    // load trie structure
    root = malloc(sizeof(node));

    // set current node
    node* current_node = root;

    // word holder
    char* word = malloc((LENGTH + 1) * sizeof(char));

    // load each word
    while(fscanf(fp, "%s", word) == 1)
    {
        // load each letter
        for (int i = 0; i < strlen(word); i++)
        {
            // letter
            if (isalpha(word[i]))
            {
                // if node don't exist
                if (current_node->children[word[i] - 'a'] == NULL)
                {
                    current_node->children[word[i] - 'a'] = malloc(sizeof(node));
                }

                // jump to next node        
                current_node = current_node->children[word[i] - 'a'];
            }

            // apostrophe
            else if (word[i] == '\'' && i > 0)
            {
                // if node don't exist
                if (current_node->children[C_LENGTH - 1] == NULL)
                {
                    current_node->children[C_LENGTH - 1] = malloc(sizeof(node));
                }

                // jump to next node        
                current_node = current_node->children[C_LENGTH - 1];
            }

            // sanity check
            else
            {
                return false;
            }

        }

        // reached end of word
        words++;
        current_node->is_word = true;
    }

    // check whether there was an error
    if (ferror(fp))
    {
        fclose(fp);
        printf("Error reading %s.\n", dictionary);
        return false;
    }  

    // close file
    fclose(fp);

    // free memory
    free(word);

    return true;
}

[code removed to comply to academic honesty]

1

Your problem is indeed in your load function. Think about what happens when you read the last letter of the first word in your dictionary. You get outside of the for loop iterating over its letters, you count one more word, you set the boolean is_word to true and then you proceed to the next word. But when you started to load this word, your initial node, was the root node. When you go to the next word, you don't revert back to the root node. You keep loading on the current_node, which at this point points to the end of the first word. So what you basically have done is load all the dictionary one word after another in a linked list. Hope you know how to solve this. If you need more details ask in the comments. I didn't want to spare you the fun of finding it out yourself. Also if this answers your question please accept it by clicking the gray check-mark to the left, so that it becomes green. You can also vote it up by pressing the up arrow above the check-mark.

Sidenote

When I run your code in GDB I got a segfault in contrary to you that you didn't. Maybe you did something wrong? Anyway that told me that the segfault happened somewhere in unload_free and then I run step by step to see what was wrong.

You must log in to answer this question.

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