This problem set is becoming my bane. I have spent hours on it and I am still getting the same issues with valgrind (definitely losing 7 million bytes). I think my issues lie with load and check and not unload or the word count. I have tried starting over and writing everything out on paper, and while that proved to tidy-up and fix some of my code, the whole of it remains broken. Help would be much appreciated :)
Global stuff and headers:
#include <stdbool.h>
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include "dictionary.h"
// define a node
typedef struct node
{
// array to store word
char new[LENGTH + 1];
//create a pointer to the next node
struct node* next;
}node;
// hash function
int hash_fxn (char* key)
{
// hash on 1st letter (apostrophe hashes to 'a')
int hash = toupper(key[0]) - 'A';
return hash % 26;
}
// create the base array of the alphabet
node* alphabet[26];
// word counter
int wordcount = 0;
Check function:
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{ // TODO
// get space for lowercase shifted word
char lowercase[strlen(word)];
// create space for new node cursor
node* cursor = NULL;
// break down word to all lower-case
for (int i = 0; i < strlen(word); i++)
lowercase[i] = tolower(word[i]);
lowercase[strlen(word)] = '\0'; // end of string marker
// go to corresponding bin for hash function and search
cursor = alphabet[hash_fxn(lowercase)];
while (cursor != NULL)
{
// compare strings with strcmp
if (strcmp(cursor->new, lowercase) == 0)
return true;
cursor = cursor->next;
}
free(cursor);
return false;
}
Load function:
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char* dictionary)
{
// TODO
// allocate space for the array of linked lists
for (int i = 0; i < 26; i++)
{
alphabet[i] = NULL;
}
// open dictionary
FILE* dict = fopen(dictionary, "r");
if (dict == NULL)
{
printf("Dictionary could not be loaded\n");
return false;
}
// create temporary placeholder node
node* temp = NULL;
// execute while the dictionary is not finished
while (!feof(dict))
{
// create space for new_node
node* new_word = malloc(sizeof(node));
// read word from dictionary and place it in new node
fscanf(dict, "%s", new_word->new);
// generate hash value
int hash_value = hash_fxn(new_word->new);
// if there is nothing already in the hash bin
if (alphabet[hash_value] == NULL)
alphabet[hash_value] = new_word; // set the bin equal to the new node
// if something is in bin insert at the head of the bin
else if (alphabet[hash_value] != NULL)
{
// insert new_word at head of linked list utilizing temporary storage
temp = alphabet[hash_value];
new_word->next = temp;
alphabet[hash_value] = new_word;
}
// add to wordcount
wordcount++;
}
// if all goes according to plan, return true
return true;
}
Unload function:
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
// TODO
for (int i = 0; i < 26; i++)
{
node* cursor = alphabet[i];
while (cursor != NULL)
{
node* temp = cursor;
cursor = cursor->next;
free(temp);
}
free(alphabet[i]);
}
return true;
}