0

My Speller function works on all the .txt files provided with the keys. I even made a .txt containing the large dictionary and all the words are spelled correctly.

However, when I go to use Check50 I fail everything except exisits and compiles: https://submit.cs50.io/check50/70297233ac3c9a8ecc0fec42a31ec0a513a9cc76

Here's the code:

// Implements a dictionary's functionality

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

int wordsInDictionary;

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

// Number of buckets in hash table
const unsigned int N = 1000;

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    char* lower = malloc(strlen(word) + 1);

    // convert the word to lowercase
    int i = 0;
    for (; i < strlen(word); i++)
    {
        if (isupper(word[i]))
        {
            lower[i] = tolower(word[i]);
        }

        else
        {
            lower[i] = (word[i]);
        }

    }

    lower[i] = '\0';
    node* c = table[hash(lower)];
    while (c != NULL)
    {
        int comp = strcmp(lower, c->word);
        if (comp == 0)
        {
            free(lower);
            return true;
        }

        c = c->next;

    }
    free(lower);
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    int q = 0; //variable for ASCII value sum of all chars in a word

    // Sum all the ASCII values in a word
    for (int j = 0; j < strlen(word); j++)
    {
        q = q + (int)word[j];
    }

    int h = q % 1000; // Compute the Hash Value

    return h;
}

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

    if(fp == NULL)
    {
      perror("Error opening file");
      return false;
    }

    char *buffer = malloc(LENGTH + 1);

    int n = 0; // buffer array index counter
    int q; // sum of charachter values for algorithm

    int c = fgetc(fp);
    while (c != EOF) // Get contents of file charachter by charachter until end of file is reached
    {


        // if a new line charachter is not encountered then the word is growing
        if (c != 10)
        {
            buffer[n] = c; // set the current buffer element at index n (array index counter) equal to the current charachter in the word
            q = q + c; // case the charachter into its ASCII interger value and add to total value
            n++; // increment the array index counter
        }

        //else means that the charachter must be a newline char, meaning the completion of a word
        else
        {
            buffer[n] = '\0'; //add the null terminator the end of the word
            int hashCode = q  % 1000; // use the algorithm to generate a hash code
            node *tmp = malloc(sizeof(node)); // Create a new dynamically allocated memory chunk

            // insert word from buffer into the dynamically allocated memory
            for (int y = 0; y < n + 1; y++)
            {
               tmp->word[y] = buffer[y];
            }


            // walk through the linked list searching for a node with a NULL next pointer

            if (table[hashCode] == NULL)
            {
                table[hashCode] =  tmp;
            }
            else
            {
                (*tmp).next = table[hashCode];
                table[hashCode] = tmp;
            }


            wordsInDictionary++; // increments words in dictionary
            n = 0;
            q = 0;
        }
        c = fgetc(fp);

    }
    free(buffer); // Free the buffer
    fclose(fp);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    return wordsInDictionary;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{

    for (int i = 0; i < 1000; i++)
    {
        while (table[i] != NULL)
        {
            node* tmp = table[i];
            table[i] = (*tmp).next;
            free(tmp);
        }
    }
    return true;
}
2
  • Wow! Ok I answered my own question. I changed the code so I actually called hash(buffer) in the load funtion. Now everything works excepts memory. Sorry everyone! Hopefully this helps the next person.. FYI I've been at this for like a week and just started posting about it haha
    – camptzak
    Commented May 28, 2020 at 15:06
  • Even I am having a problem with memory.
    – Vsjain
    Commented Jun 2, 2020 at 7:28

1 Answer 1

0

Your table is not fully initialized. The following is the error message reported by our tools.

  Memory access warning: reading uninitialized memory; continue execution.
  # Reading 4 bytes from 0x80906c0 will read undefined data.
  #
  # The memory-space-to-be-read (start:0x8090414, size:4000 bytes) is bound to 'table' at
  #    file:/dictionary.c::24, 0
  # It is not initialized.
  #
  #  0x8090414               0x80913b3
  #  +------------------------------+
  #  | the memory-space-to-be-read  |
  #  +------------------------------+
  #                  ^~~~~~~~~~
  #      the read starts at 684 bytes offset of the memory-space.
  #
  # Stack trace (most recent call first) of the read.
  # [0]  file:/dictionary.c::161, 9
  # [1]  file:/speller.c::152, 21
  # [2]  [libc-start-main]
  # This detection can be configured with DTS_MEMORY_UNINIT_CHECK=<error|warning|disabled>.

Here is the link to reproduce this error.

You must log in to answer this question.

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