0

I've been stuck on this problem set for a while now. Valgrind is telling me I have a problem in my unload function, which is "Conditional jump or move depends on uninitialised value(s)". I can't find exactly where my error is. I would appreciate any help with this. This is my code:

// Implements a dictionary's functionality
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <strings.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 = 27;

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
int bucket = hash(word);
for(node *tmp = table[bucket]; tmp != NULL; tmp = tmp->next)
{
    if (strcasecmp(tmp->word, tmp->next->word) == 0)
    {
        return true;
    }
}
return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
  int return_value = (word[0] - 'a');
  return return_value;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
   char words[LENGTH + 1];
   FILE *d = fopen(dictionary, "r");
   if (d == NULL)
   {
      return false;
   }
   do
   {
    node *current = malloc(sizeof(node));
    if (current == NULL)
    {
        return false;
    }
    strcpy(current->word, words);
    current->next = NULL;
    int hashed_word = hash(current -> word);

    if (table[hashed_word] == NULL)
    {
        table[hashed_word] = current;
    }
    else
    {
        current->next = table[hashed_word];
        table[hashed_word] = current;
    }
 }
 while (fscanf(d, "%s", words) != EOF);
 return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
  int word_count = 0;
  for (int i = 0; i < N; i++)
  {
    for (node *tmp = table[i]; tmp != NULL; tmp = tmp->next)
    {
        word_count++;
    }
  }
  return word_count;
  }
   // Unloads dictionary from memory, returning true if successful else false  
   bool unload(void)  
   {  
       for (int i = 0; i <= 27; i++)
       {
           for (node *pointer = table[i]; pointer != NULL; pointer = pointer->next)
           {
               if (pointer == NULL)
               {
                   free (pointer);
                   return false;
               }
               else
               {
                   node *tmp = pointer;
                   if (tmp == NULL)
                   {
                      free (tmp);
                      return false;
                   }
                   free (tmp);
               }
           }
       }
       return true;
   }
1

Two problems. First, table[] was never initialized. Second, the if statement in unload allows i to be 27, which means that table[27] is selected, but doesn't exist.

There may be other issues, but these two jumped out at me.

[Edit] There's a third problem. The do/while loop in load will try to process a word read from the dictionary, but since it's a do/while, the first word isn't read until the end of the loop! That causes the seg fault. Try a plain while loop instead.

Also, there's another seg fault lying in wait, but it's a totally different issue and deserves a new question. ;-)

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

3
  • Table[] was initialized after N was initialized, at the top. I changed my for loop to for(int i = 0; i < 27; i++), so that problem is fixed, but I still have a segmentation fault. – mkg15 Jun 13 '20 at 21:03
  • See edited answer. Also, seg faults are a totally new problem, unrelated to valgrind and deserve new questions. – Cliff B Jun 13 '20 at 21:32
  • Thanks, that did get rid of that seg fault and now I'm working on the other one. – mkg15 Jun 13 '20 at 23:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .