Thanks in advance for helping out an old Dutchie!
I am almost there, but valgrind insists i have an uninitialised value on in the While loop: while (cursor != NULL)
VALGRIND tells me ==1590== Conditional jump or move depends on uninitialised value(s) ==1590== at 0x4013ED: unload (dictionary.c:148) ==1590== by 0x400E59: main (speller.c:152)
==1590== All heap blocks were freed -- no leaks are possible ==1590== ==1590== For counts of detected and suppressed errors, rerun with: -v ==1590== ERROR SUMMARY: 541 errors from 1 contexts (suppressed: 0 from 0)
Asking for help...
==1590== Conditional jump or move depends on uninitialised value(s)
Looks like you're trying to use a variable that might not have a value? Take a closer look at line 148 of dictionary.c.
My code:
// Implements a dictionary's functionality
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
unsigned int word_count = 0;
// Number of buckets in hash table
const unsigned int N = 541; // adjusted manually
// Hash table
node *hashtable[N];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
// get to lowercase
char *copy_word = malloc(sizeof(char) * (LENGTH + 1));
copy_word = strcpy(copy_word, word); //take input word and copy it into non const variable
int i = 0;
while (i < strlen(copy_word))
{
copy_word[i] = tolower(copy_word[i]);
i++;
}
int bucket = hash(copy_word);
node *lili2 = hashtable[bucket];
while (lili2->next != NULL)
{
if (strcasecmp (lili2->word, copy_word) != 0)
{
lili2 = lili2->next;
}
else
{
printf("dit woord in dic gevonden: %s \n", word);
return true;
}
}
free(copy_word);
return false;
}
// Hashes word to a number, djb2 hash function from http://www.cse.yorku.ca/~oz/hash.html
unsigned int hash(const char *word)
{
unsigned int hash = 5381;
int c;
while ((c = *word++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
// ALTERNATIVE HASH FUNCTION TRIED, BUT GENERATING SAME RESULT
// unsigned int hash = 0;
// for (int i = 0, n = strlen(word); i < n; i++)
// hash = (hash << 2) ^ word[i];
return hash % N; //N is size of hashtable;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE *file;
char word[LENGTH + 1];
unsigned int bucket_ptr;
file = fopen(dictionary, "r"); // opens dictionary (skipped checking if a dictionary was specified...)
if (file == NULL) // check if return value is NULL
{
printf("Forensic image cannot be opened for reading..\n");
return false;
}
while (fscanf(file, "%s", word) != EOF)
{
fscanf(file, "%s", word);
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
printf("cld not malloc a new node. \n");
unload();
return false;
}
strcpy (new_node->word, word);
bucket_ptr = hash(word);
if (hashtable[bucket_ptr] == NULL)
{
hashtable[bucket_ptr] = new_node;
// new_node->next = NULL;
}
else
{
new_node->next = hashtable[bucket_ptr];
hashtable[bucket_ptr] = new_node;
}
word_count++;
}
printf("load finished; wordcount is %i\n", word_count); // check
fclose(file); // necessary ??
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return word_count;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i <= N; i++) // (or <N ?)
{
node *cursor = hashtable[i];
node *tmp = hashtable[i];
while (cursor != NULL)
{
cursor = cursor->next;
free(tmp);
tmp = cursor;
}
}
return true; // if done succesfull
// return false // when return false...?
}