So i am so close to finally completing this present and i still have some final errors to go through. Valgrind is saying that it is still leaking memory for some reason and i cant find the reason why.

error below:
```
running valgrind --show-leak-kinds=all --xml=yes --xml-file=/tmp/tmpnbjzjhsm -- ./speller substring/dict substring/text...
checking for output "MISSPELLED WORDS\n\nca\ncats\ncaterpill\ncaterpillars\n\nWORDS MISSPELLED: 4\nWORDS IN DICTIONARY: 2\nWORDS IN TEXT: 6\n"...
checking that program exited with status 0...
checking for valgrind errors...
112 bytes in 2 blocks are still reachable in loss record 1 of 1: (file: dictionary.c, line: 89)
```
valgrind has this see below:
```
^C==5410==

==5410== Process terminating with default action of signal 2 (SIGINT)

==5410== at 0x4C2F3C0: ??? (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==5410== by 0x4C3361D: strcasecmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==5410== by 0x40108F: check (dictionary.c:36)

==5410== by 0x400C89: main (speller.c:112)

==5410==

==5410== HEAP SUMMARY:

==5410== in use at exit: 8,013,648 bytes in 143,092 blocks

==5410== total heap usage: 143,096 allocs, 4 frees, 8,023,416 bytes allocated

==5410==

==5410== 552 bytes in 1 blocks are still reachable in loss record 1 of 3

==5410== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==5410== by 0x5258E49: __fopen_internal (iofopen.c:65)

==5410== by 0x5258E49: fopen@@GLIBC_2.2.5 (iofopen.c:89)

==5410== by 0x400A23: main (speller.c:55)

==5410==

==5410== 920,192 bytes in 16,432 blocks are still reachable in loss record 2 of 3

==5410== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==5410== by 0x4011FB: load (dictionary.c:89)

==5410== by 0x400964: main (speller.c:40)

==5410==

==5410== 7,092,904 bytes in 126,659 blocks are definitely lost in loss record 3 of 3

==5410== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==5410== by 0x4011FB: load (dictionary.c:89)

==5410== by 0x400964: main (speller.c:40)

==5410==

==5410== LEAK SUMMARY:

==5410== definitely lost: 7,092,904 bytes in 126,659 blocks

==5410== indirectly lost: 0 bytes in 0 blocks

==5410== possibly lost: 0 bytes in 0 blocks

==5410== still reachable: 920,744 bytes in 16,433 blocks

==5410== suppressed: 0 bytes in 0 blocks

==5410==

==5410== For counts of detected and suppressed errors, rerun with: -v

==5410== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
```


code starts below -----

```c
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "dictionary.h"
#include "string.h"
#include <ctype.h>
#include <strings.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 = 10000;
int number_words = 0;

// Hash table
node *table[N];  // array of node pointer every element in that arraay is a pointer change it to some higher value and can spread buckets

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    int index = hash(word);
    
    node*cursor = table[index];
    
    while (cursor != NULL)
    {
        
        if (strcasecmp(cursor ->word, word) == 0)
        {
            
            return true;
            
        }
        
        else 
        {
            cursor = cursor -> next;
        }
        
    }
    
    return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
    // TODO
    unsigned int hashvalue = 0;
    for (int i = 0 ; word[i] != '\0'; i++)
    {
        hashvalue += tolower(word[i])* (i + 1);
    }
 return hashvalue % N;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{


    FILE *file = fopen(dictionary, "r");

    if (file == NULL)
    {
        printf("there is an error on file open");
        return 1;
    }
    
    
    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }

    char words[45];

    while(fscanf(file, "%s", words) != EOF)
    {
        node *n = malloc(sizeof(node));

        if (n == NULL)
        {
            printf("with n in 63");
            unload();
            return 1;
        }

        strcpy(n ->word, words);
        n -> next = NULL;
        number_words++;

        int h_index = hash(words);
        
        
        if (table[h_index] == NULL)
        {
            table[h_index] = n;
            n -> next = NULL;
            
        }
        
        if (table[h_index] != NULL)
        {
            
            n -> next = table[h_index];
            table[h_index] -> next = n;
        }
    
    }
    fclose(file);
    return true;


}

// Returns number of words in dictionary if loaded else 0 if not yet loaded

unsigned int size(void)
{
    return number_words;
    return 0;
}

// Unloads dictionary from memory, returning true if successful else false//

   bool unload(void)
{
    for(int i = 0; i < N; i++)
    {
        
        node *head = table[i];
        node *cursor = head;
        
        while (cursor != NULL)
        {
            node *tmp = cursor;
            cursor = cursor -> next;
            free(tmp);
            tmp = cursor;
        }
    
        return true;
    
    }
    
    return false;
```