0

valgrind is showing me an error that I have trouble understanding. The error is "conditional jump or move depends on uninitialised value(s)". Valgrind is directing me to line 125 of my code, which is my unload function at the bottom. I guess It's telling me that I haven't initialized the cursor node? How can it be uninitialized when I set it to NULL, then set it to the head of the hashtable? Here's my code, and I've pointed out which line valgrind is referring to. Any help would be appreciated!

enter image description here

// Implements a dictionary's functiionality
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>


#include "dictionary.h"

unsigned int hash_index(const char *word);

// 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;

// Hash table
node *table[N];

int dictsize = 0;

bool check(const char *word)
{
    //create copy of word and set it to lowercase
    int n = strlen(word);
    char word_copy[LENGTH + 1];

    for (int i = 0; i < n; i++)
    {
        word_copy[i] = tolower(word[i]);
    }

    word_copy[n] = '\0';

    //hash word
    int hash_number = hash_index(word_copy);
    //create cursor
    node *cursor  = NULL;
    cursor = table[hash_number];

    while (cursor != NULL)
    {
        if (strcasecmp(cursor->word, word_copy)==0)
        {
            return true;
        }
        cursor = cursor -> next;
    }
    return false;
}

// Hash function posted by reddit user delipity
unsigned int hash_index(const char *word)
{
    unsigned int hash = 0;
    for (int i = 0, n = strlen(word); i < n; i++)
    {
        hash = (hash << 2) ^ word[i];
    }
    return hash % N;
}

bool load(const char *dictionary)
{
    //open file
    FILE *dict = fopen(dictionary, "r");
    if (dict == NULL)
    {
        printf("Cannot open file\n");
        return false;
    }
//create array to place word
    char word[LENGTH + 1];
//load into hash table
    while (fscanf(dict, "%s", word) != EOF)
    {
        node *new_node = malloc(sizeof(node));
        if (new_node == NULL)
        {
            printf("no new_node\n");
            return false;
        }

        dictsize++;

        strcpy(new_node->word, word);

        int hash_code = hash_index(new_node -> word);

        if (table[hash_code] == NULL)
        {
            table[hash_code] = new_node;
        }
        else
        {
            new_node->next = table[hash_code];
            table[hash_code] = new_node;
        }
    }
    fclose(dict);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    return dictsize;
}

bool unload(void)
{
    for (int i = 0; i < N; i++)
    {//create cursor
        node *cursor = NULL;
        cursor = table[i];

        while (cursor != NULL)//***THIS IS WHERE VALGRIND IS POINTING TO
        {//create tmp variable that will be behind cursor, free current memory, then point to cursor
            node *tmp = cursor;
            cursor = cursor -> next;
            free(tmp);
        }
    }
    return true;
}
0

The uninitialized value isn't cursor, it's table[i]. Since the table[] array is never initialized (it should have been initialized in load), cursor is set to the same value as table[i], whether it was set to a legitimate address, or never set to anything and therefore contains junk data.

The compiler is recognizing that it is theoretically possible that cursor could have an undefined value assigned to it.

This is a good question! It shows how a problem in one place can manifest in another. It demonstrates the need to look at everything related to a problem variable or valgrind report.

And always remember, valgrind is usually telling you where the memory related to a problem is allocated, not necessarily where the problem lies, and where it sees that something looks wrong, but not necessarily where the cause lies!

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

1
  • Hi guys, I don't know if either of you are still active, but if so, could you please check out my questions on this issue. I know it must be similar to this, but initializing table[i] hasn't solved the problem. The question is: PSET5/Speller - Valgrind error: conditional jump, relates to table[i] array, but I've already initialized that (or have I?)? Link: cs50.stackexchange.com/questions/40406/… – cormacl Dec 19 '20 at 21:28

You must log in to answer this question.

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