title: cs50 Pset5 Speller segmentation fault and memory leaks
body: <p>So i have been trying to complete the cs50, Problem Set 5, speller problem and i have done the entire code without any reference except their own walkthrough videos on their website.</p>
  <p>i have tried looking at other people's code but there is some problem with my code that I just don't get why it is happening.
  the code compiles fine, but gives a segmentation fault.</p>
  <p>when i use valgrind then it tells me that there are many leaks and files needed to be closed, but i have already done all those changes wherever needed and compiled my code several times already.</p>
  <p>Here's my code</p>
  <pre><code>#include &lt;cs50.h&gt;
  #include &lt;stdbool.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;strings.h&gt;
  
  #include &quot;dictionary.h&quot;
  
  // Represents a node in a hash table
  typedef struct node
  {
      char word[LENGTH + 1];
      struct node *next;
  }
  node;
  
  // TODO: Choose number of buckets in hash table
  // LENGTH is a const int = 45
  const unsigned int N = LENGTH; 
  
  // Hash table
  node *table[N];
  
  // Size no.
  int size_number = 0;
  
  // Returns true if word is in dictionary, else false
  bool check(const char *word)
  {
      int n = hash(word);
  
      for (node *cursor = table[n]; cursor-&gt;next != NULL; cursor = cursor-&gt;next)
      {
          if (strcasecmp(cursor-&gt;word, word) == 0)
          {
              return true;
          }
      }
      return false;
  }
  
  // Hashes word to a number
  unsigned int hash(const char *word)
  {
      int n = -1;
      for (int i = 0; i &lt; strlen(word); i++)
      {
          if (isalpha(word[i]) || word[i] == '\'')
          {
              n++;
          }
      }
      return n;
  }
  
  // Loads dictionary into memory, returning true if successful, else false
  bool load(const char *dictionary)
  {
      FILE *dict = fopen(dictionary, &quot;r&quot;);
      if (dict == NULL)
      {
          printf(&quot;Could not open dictionary\n&quot;);
          return false;
      }
      char word[N];
  
      while(fscanf(dict, &quot;%s&quot;, word))
      {
          int n = fscanf(dict, &quot;%s&quot;, word);
          if (n == EOF)
          {
              break;
          }
          size_number++;
  
          node *loaded_word = malloc(sizeof(node));
          if (loaded_word == NULL)
          {
              fclose(dict);
              return false;
          }
          strcpy(loaded_word-&gt;word, word);
  
          int index = hash(loaded_word-&gt;word);
  
          loaded_word-&gt;next = table[index];
          table[index]-&gt;next = loaded_word;
      }
  
      fclose(dict);
  
      return true;
  }
  
  // Returns number of words in dictionary if loaded, else 0 if not yet loaded
  unsigned int size(void)
  {
      return size_number;
  }
  
  // Unloads dictionary from memory, returning true if successful, else false
  bool unload(void)
  {
      for (int i = 0; i &lt; N; i++)
      {
          while(table[i] != NULL)
          {
              node *tmp = table[i]-&gt;next;
              free(table[i]);
              table[i] = tmp;
          }
      }
      return true;
  }
  </code></pre>
  <p>i used it with</p>
  <pre><code>valgrind ./speller texts/cat.txt
  </code></pre>
  <p>cat.txt is</p>
  <pre><code>A cat is not a caterpillar.
  </code></pre>
  <p>and here's the valgrind output</p>
  <pre><code>==6031== Invalid write of size 8
  ==6031==    at 0x401BDE: load (dictionary.c:90)
  ==6031==    by 0x4012BE: main (speller.c:40)
  ==6031==  Address 0x30 is not stack'd, malloc'd or (recently) free'd
  ==6031== 
  ==6031== 
  ==6031== Process terminating with default action of signal 11 (SIGSEGV): dumping core
  ==6031==  Access not within mapped region at address 0x30
  ==6031==    at 0x401BDE: load (dictionary.c:90)
  ==6031==    by 0x4012BE: main (speller.c:40)
  ==6031==  If you believe this happened as a result of a stack
  ==6031==  overflow in your program's main thread (unlikely but
  ==6031==  possible), you can try to increase the size of the
  ==6031==  main thread stack using the --main-stacksize= flag.
  ==6031==  The main thread stack size used in this run was 8388608.
  ==6031== 
  ==6031== HEAP SUMMARY:
  ==6031==     in use at exit: 528 bytes in 2 blocks
  ==6031==   total heap usage: 3 allocs, 1 frees, 4,624 bytes allocated
  ==6031== 
  ==6031== 56 bytes in 1 blocks are still reachable in loss record 1 of 2
  ==6031==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==6031==    by 0x401B74: load (dictionary.c:79)
  ==6031==    by 0x4012BE: main (speller.c:40)
  ==6031== 
  ==6031== 472 bytes in 1 blocks are still reachable in loss record 2 of 2
  ==6031==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==6031==    by 0x4A2592D: __fopen_internal (iofopen.c:65)
  ==6031==    by 0x4A2592D: fopen@@GLIBC_2.2.5 (iofopen.c:86)
  ==6031==    by 0x401ACE: load (dictionary.c:62)
  ==6031==    by 0x4012BE: main (speller.c:40)
  ==6031== 
  ==6031== LEAK SUMMARY:
  ==6031==    definitely lost: 0 bytes in 0 blocks
  ==6031==    indirectly lost: 0 bytes in 0 blocks
  ==6031==      possibly lost: 0 bytes in 0 blocks
  ==6031==    still reachable: 528 bytes in 2 blocks
  ==6031==         suppressed: 0 bytes in 0 blocks
  ==6031== 
  ==6031== For lists of detected and suppressed errors, rerun with: -s
  ==6031== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
  /opt/cs50/bin/valgrind: line 11:  6031 Segmentation fault      (core dumped)
  </code></pre>
  <p>i have closed the dict file and freed memory wherever i think it was needed, but it still gives me the same output, and i cannot pinpoint the problem or problems in the code. any help is appreciated. :)</p>
  <p>EDIT: I forgot to tell about how my hash function works. my hash function sorts the words  according to their length, so how many letters a word has, so 'apple' and 'action' are in different linked lists, but 'action' and 'banana' are in the same. this is why no. of buckets = LENGTH which is the lengthiest word possible for this problem.</p>