I have some issues with the CS50 speller task in problem set 5. For those who are not familiar with this problem, basically my program works as a spell checker (you insert a dictionary and a text file and the program returns all misspelled words). Our task was to write five functions (check, hash, load, size, unload). The check function checks if a word is in set dictionary. Hash basically returns a numerical index of the hash table I used to organise the words in based on the input of a word from the text. The load function basically loads all the words from the dictionary file into the hash table. The size function returns the size of the dictionary and finally the unload functions frees all memory allocated to my program. However, when I test my program with check50 there is apparently a fault with the freeing of memory. However, I don't know where this issue could be?
Thanks in advance!
// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <stdlib.h>
#include "dictionary.h"
// 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 = 26;
// Hash table
node *table[N];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
int x = hash(word);
for (node *temp = table[x]; temp != NULL; temp = temp->next)
{
if (strcasecmp(word, temp->word) == 0)
{
return true;
}
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
char s = word[0];
if(word[0] < 97)
{
s = tolower(word[0]);
}
int index = s - 97;
return index;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// TODO
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
printf("Could not open dictionary.\n");
return false;
}
char theword[45];
while (fscanf(file, "%s", theword) != EOF)
{
node *n = malloc(sizeof(node));
if (n == NULL)
{
return false;
}
int wordlength = strlen(theword);
int x = hash(theword);
char tempword[45];
if (table[x] == NULL)
{
for (int j = 0; j < wordlength; j++)
{
n->word[j] = theword[j];
}
n->next = NULL;
table[x] = n;
}
for (node *temp = table[x]; temp != NULL; temp = temp->next)
{
node *temp2 = temp->next;
if (temp2 == NULL)
{
for (int k = 0; k < strlen(theword); k++)
{
n->word[k] = theword[k];
}
temp->next = n;
n->next = NULL;
}
}
}
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
int count = 0;
for (int i = 0; i < N; i++)
{
for (node *temp = table[i]; temp != NULL; temp = temp->next)
{
count++;
}
}
return count;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
node *temp = table[i];
while (temp != NULL)
{
node *temp2 = temp->next;
free(temp);
temp = temp2;
}
}
return true;
}
load
function you haveif (table[x] == NULL)
for an empty bucket, but shouldn't the followingfor
loop be in anelse
block so it only gets executed when the bucket is not empty? - Johnny Mopp