Home > Enterprise >  CS50 Speller - Check function stops working after finding first 4 misspelled words
CS50 Speller - Check function stops working after finding first 4 misspelled words

Time:06-18

I am working on problem set 5 in CS50x2022: speller. After some time I finally managed to make my code somehow "work properly". the check function does work at start but after finding a few misspelled words it stops. Debug50 shows the error "Unknown stopping event". What can be the source of that?

bool check(const char *word)
{
    node *cursor = malloc(sizeof(node));
    int hash_word = hash(word);
    cursor->next = table[hash_word]->next;
    while (cursor->next != NULL)
    {
        if (strcasecmp(word, cursor->next->word) == 0)
        {
            return true;
        }
        else
        {
           cursor = cursor->next;
        }
    }
    free(cursor);
    return false;
}

Here is my load function since there might be the source of the problem? But as I checked, it loaded every word from a dictionary right, but in case here it is.

// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
    for (int z = 0; z < N; z  )
    {
        table[z] = malloc(sizeof(node));
        table[z]->next = NULL;
    }
    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        return 1;
    }
    for (int i = 0; i < 143091; i  ) //143091
    {
        number_of_words = number_of_words   1;
        char word[LENGTH   1];
        fscanf(file, "%s", word);
        node *n = malloc(sizeof(node));
        if (n == NULL)
        {
            return 1;
        }
        strcpy(n->word, word);
        int number = hash(n->word);
        n->next = table[number]->next;
        table[number]->next = n;
    }
    fclose(file);
    return true;
}

CodePudding user response:

There is no reason for the check function to allocate memory. It should just iterate on the list pointed to by the hash table entry.

Furthermore you test each entry pointed to by cursor, not cursor->next.

Here is a modified version:

bool check(const char *word) {
    int hash_word = hash(word);
    node *cursor = table[hash_word]
    while (cursor != NULL) {
        if (strcasecmp(word, cursor->word) == 0) {
            return true;
        }
        cursor = cursor->next;
    }
    return false;
}

Loading the dictionary is incorrect too:

  • do not allocate a dummy node for each entry in the hash table, just initialize the array with null pointers.
  • don't make an assumption about the number of words.
  • do test for fscanf() successful conversions.
  • avoid potential buffer overflows by tell fscanf() the maximum number of characters to store into the destination array.
  • return false in case of error and close the file.
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary) {
    number_of_words = 0;
    for (int z = 0; z < N; z  ) {
        table[z] = NULL;
    }
    FILE *file = fopen(dictionary, "r");
    if (file == NULL) {
        return false;
    }
    char word[64   1];
    // read all words from the dictionary.
    // no assumption on the number of words
    while (fscanf(file, "ds", word) == 1) {
        node *n = malloc(sizeof(node));
        if (n == NULL) {
            fclose(file);
            return false;
        }
        strcpy(n->word, word);
        int key = hash(n->word);
        n->next = table[key];
        table[key] = n;
        number_of_words  = 1;
    }
    fclose(file);
    return true;
}
  • Related