My code is
// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <ctype.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 = 676;
// Hash table
node *table[N];
// size of dictionary
int lines = 0;
// Returns true if word is in dictionary else false
bool check(const char *word)
{
// TODO
int a = 0;
int c = strlen(word);
int b = hash(word);
node *cursor = table[b];
while(cursor != NULL)
{
int d = strcasecmp(cursor -> word, word);
if(d != 0)
{
cursor = cursor -> next;
}
else
{
a = 1;
break;
}
}
if(a == 1)
{
return true;
}
else
{
return false;
}
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO
int a = 0,b,c = 0,e;
e = strlen(word);
char d;
if(e > 1)
{
if ('A' <= word[0] && word[0] <= 'Z')
{
a = (word[0] % 65);
}
else
{
a = (word[0] % 97);
}
if ('A' <= word[1] && word[1] <= 'Z')
{
b = (word[1] % 65);
}
else
{
b = (word[1] % 97);
}
c = (a * 26) + b;
}
else
{
if ('A' <= word[0] && word[0] <= 'Z')
{
a = (word[0] % 65);
}
else
{
a = (word[0] % 97);
}
c = (a * 26);
}
return c;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// TODO
FILE *dictionary1;
dictionary1 = fopen (dictionary, "r");
char a[46];
char b;
int c;
int n = 0;
int j;
node *f = NULL;
if (dictionary1 == NULL)
{
return false;
}
else
{
while((b = fgetc(dictionary1)) != EOF)
{
if(b == '\n')
{
lines++;
}
}
fseek(dictionary1, 0, SEEK_SET);
for(int i = 0; i < lines; i++)
{
a[0] = fgetc(dictionary1);
while(a[n] != '\n')
{
a[n + 1] = fgetc(dictionary1);
n++;
}
a[n + 1] = '\0';
n = 0;
j = hash(a);
f = malloc(sizeof(node));
f -> next = NULL;
int y =strlen(a);
if (y == 2)
{
if (a[0] > 'A' && a[0] < 'Z')
{
c = a[0] - 65;
j = c * 26;
}
else
{
c = a[0] - 97;
j = c * 26;
}
}
for (int k = 0; k < y - 1; k++)
{
f -> word[k] = a[k];
}
if (i == 0)
{
table[j] = f;
}
else
{
f -> next = table[j];
table[j] = f;
}
f = NULL;
}
fclose (dictionary1);
return true;
}
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
// TODO
return lines;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// TODO
for (int i = 0; i < 676; i++)
{
node *cursor = table[i], *tmp = cursor;
while(cursor != NULL)
{
cursor = cursor -> next;
free(tmp);
tmp = cursor;
}
}
return true;
}
on running valgrind it shows
Conditional jump or move depends on uninitialised value(s)
at 0x520A60F: tolower (ctype.c:46)
by 0x4C3361D: strcasecmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x401034: check (dictionary.c:39)
by 0x400C19: main (speller.c:112)
Uninitialised value was created by a heap allocation
at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x4012F4: load (dictionary.c:139)
by 0x4008F4: main (speller.c:40)
Use of uninitialised value of size 8
at 0x520A623: tolower (ctype.c:46)
by 0x4C3361D: strcasecmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x401034: check (dictionary.c:39)
by 0x400C19: main (speller.c:112)
Uninitialised value was created by a heap allocation
at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x4012F4: load (dictionary.c:139)
by 0x4008F4: main (speller.c:40)
Please help me fix this.