0

After i finished the code for load() and check(), I ran speller to find out if it was running correctly. Unfortunately, after finding some mispelled words, I get a segmentation fault message. Can someone shed some light on what i am doing wrong?

Speller output:

~/workspace/pset5/ $ ./speller texts/alice.txt
MISSPELLED WORDS
Gutenberg's
Alice's
eBook
eBook
org
Alice's
EBook
EBOOK
ALICE'S
ALICE'S
Segmentation fault

The following is my dictionary.c:

/**
 * dictionary.c
 *
 * Computer Science 50
 * Problem Set 5
 *
 * Implements a dictionary's functionality.
 */

#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "dictionary.h"


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

// declare pointer to root node
node* root;

/**
 * Returns true if word is in dictionary else false.
 */
bool check(const char* word)
{
    //traverse through trie
    node* crawler = root;

    //for each letter in the word
    int n;
    n = strlen(word);
    int index;
    for (int i = 0; i < n; i++)
    {
        //go to corresponding element in children
        index = word[i];
        if (index == '\'')
        {
            index = 26;
        }
        else
        {
            index = tolower(index);
            index = index - 97;
        }
        crawler = crawler->children[index];

        //if not NULL move to next letter (do nothing)

        //if at end of word, check if is_word is true
        if (i == n - 1)
        {
            return crawler->is_word;
        }

        //if NULL return false
        else if (crawler == NULL)
        {
            return false;
        }
    }
    return false;
}

/**
 * Loads dictionary into memory.  Returns true if successful else false.
 */
bool load(const char* dictionary)
{
   // open dictionary
    FILE* fp = fopen(dictionary, "r");

    // allocate memory to root and declare crawler
    root = calloc(1, sizeof(node));
    node* crawler = root;

    //iterate through the trie for every word in dictionary
    for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
    {
        // append characters of each word to the trie
        if (isalpha(c))
        {
            //convert the letter to the correspondent index of children
            c = c - 97;

            //check if there already is a node and create one in case it's necessary
            if (crawler->children[c] != NULL)
            {
                crawler = crawler->children[c];
            }
            else
            {
                crawler->children[c] = malloc(sizeof(node));
                crawler = crawler->children[c];
            }
        }

        //append appostrophes as if they were letters
        else if (c == '\'')
        {
            //convert the letter to the correspondent index of children
            c = 26;

            //check if there already is a node and create one in case it's necessary
            if (crawler->children[c] != NULL)
            {
                crawler = crawler->children[c];
            }
            else
            {
                crawler->children[c] = malloc(sizeof(node));
                crawler = crawler->children[c];
            }
        }

        // at end of word, set is_word to true
        else
        {
            crawler->is_word = true;
            crawler = root;
        }


    }
    //close dictionary
    fclose(fp);

    return true;
}
1

It's an issue of ordering in check(). The code checks to see whether crawler == NULL as the last operation in the for loop. This means that crawler can be set to NULL, and can try to return is_word when there's no node to access. The check for NULL should be done immediately after crawler is updated.

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

1
  • That worked! Many thanks =) – Pedro Luz Dec 6 '16 at 14:25

You must log in to answer this question.

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