I worked on the speller code for bath 2020 for cs50x course.
My code passed all test cases but got stuck at a valgrind error.
Im new to this and Im unable to comprehend valgrind logs.
Please help understand where am I going wrong and give me a direction to resolve my errors
// Implements a dictionary's functionality
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <stdbool.h>
#include "dictionary.h"
int debuglevel = 2;
// 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)
{
node *head = table[hash(word)];
node *cursor = head;
while (cursor != NULL)
{
if (strcasecmp(word, cursor->word) == 0)
{
//printf("Found the matching word in dictionary at hashbucket: %d, word is: %s, dictionary word is: %s, cursor is pointing to: %p\n", hash(word), word, cursor->word, cursor);
return true;
}
if (debuglevel > 4)
{
printf("Trying to match word [%s] in dictionary word: [%s] in hashbucket: [%d], cursor is pointing to: %p\n", word, cursor->word,
hash(word), cursor);
}
cursor = cursor->next;
}
// TODO
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
int code = word[0] < 97 ? word[0] + 32 - 97 : word[0] - 97;
// TODO
return code;
}
node *front(node *head, char word[LENGTH + 1])
{
node *p;
p = malloc(sizeof(node));
strncpy(p->word, word, strlen(word) - 1);
p->next = head;
return (p);
}
int count = 0;
int hashbucket;
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE *fp;
char *line = NULL;
size_t len = 0;
ssize_t read;
node *tmp1 = malloc(sizeof(node));
for (int i = 0; i < 26; i++)
{
table[i] = malloc(sizeof(node));
table[i]->next = NULL;
}
fp = fopen(dictionary, "r");
if (fp == NULL)
{
printf("Couldn't open file [dictionaries/large] to read\n");
return false;
}
while ((read = getline(&line, &len, fp)) != -1)
{
hashbucket = line[0] < 97 ? line[0] + 32 - 97 : line[0] - 97;
// printf("populating hashbucket: [%d] with [%s] of length: [./speller texts/lalaland.txt%zd]\n", hashbucket, line, read);
// node *tmp = malloc(sizeof(node)); //create a tmp node and populate it with this new word in >>line<<
// strcpy(tmp->word, line);
table[hashbucket] = front(table[hashbucket], line);
}
fclose(fp);
for (int i = 0; i < 26; i++)
{
tmp1 = table[i];
// printf("Printing contents of table[%d]\n", i);
while (tmp1->next != NULL)
{
// printf("word from linked list is [%s] with address of struct: [%p] and address of tmp1->word: [%p] and address of tmp1->next: [%p]\n", tmp1->word, tmp1, tmp1->word, tmp1->next);
tmp1 = tmp1->next;
count++;
}
}
free(tmp1);
free(line);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
// TODO
return count;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < 26; i++)
{
node *cursor = table[i];
while (cursor != NULL)
{
node *tmp = cursor;
cursor = cursor->next;
free(tmp);
}
free(cursor);
}
// TODO
return true;
}
:) dictionary.c, dictionary.h, and Makefile exist
:) speller compiles
:) handles most basic words properly
:) handles min length (1-char) words
:) handles max length (45-char) words
:) handles words with apostrophes properly
:) spell-checking is case-insensitive
:) handles substrings properly
:( program is free of memory errors valgrind tests failed; rerun with --log for more information.