0

I'm just minutes away from solving my problem in pset5. But I'm getting the following error from valgrind.

==12523== HEAP SUMMARY:
==12523==     in use at exit: 0 bytes in 0 blocks
==12523==   total heap usage: 143,096 allocs, 143,096 frees, 8,023,416 bytes allocated
==12523== 
==12523== All heap blocks were freed -- no leaks are possible
==12523== 
==12523== ERROR SUMMARY: 112424 errors from 2 contexts (suppressed: 0 from 0)
==12523== 
==12523== 56212 errors in context 1 of 2:
==12523== Conditional jump or move depends on uninitialised value(s)
==12523==    at 0x4C30CF1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12523==    by 0x401317: unload (dictionary.c:148)
==12523==    by 0x400E09: main (speller.c:152)
==12523==  Uninitialised value was created by a heap allocation
==12523==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12523==    by 0x4011ED: load (dictionary.c:101)
==12523==    by 0x400964: main (speller.c:40)
==12523== 
==12523== 
==12523== 56212 errors in context 2 of 2:
==12523== Conditional jump or move depends on uninitialised value(s)
==12523==    at 0x4012E1: unload (dictionary.c:142)
==12523==    by 0x400E09: main (speller.c:152)
==12523==  Uninitialised value was created by a heap allocation
==12523==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12523==    by 0x4011ED: load (dictionary.c:101)
==12523==    by 0x400964: main (speller.c:40)
==12523== 
==12523== ERROR SUMMARY: 112424 errors from 2 contexts (suppressed: 0 from 0) 

And here's my full set of code:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "dictionary.h"
#include <string.h>
#include <cs50.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 = 65536;

// Hash table
node *table[N];

int dic_size = 0;
// declare hashtable

// hash funtion
// Source: djib2 by Dan Bernstein (http://www.cse.yorku.ca/~oz/hash.html)
unsigned int hash(const char *word)

{

unsigned long hash = 5381;

int c = *word;

c = tolower(c);

while (*word != 0)

{

hash = ((hash << 5) + hash) + c;

c = *word++;

c = tolower(c);

}

return hash % N;

}

/**
 * Returns true if word is in dictionary else false.
 */
bool check(const char *word)
{
    unsigned long index = hash(word);
    node *cursor = table[index];
    char dic[LENGTH + 1];
    strcpy(dic, word);
    while(cursor != NULL)
    {

        if (strcasecmp(cursor->word, dic) == 0)
        {
            return true;
        }
        else
        {
            cursor = cursor->next;
        }
    }
    // TODO
    return false;
}



/**
 * Loads dictionary into memory. Returns true if successful else false.
 */
bool load(const char *dictionary)
{
    FILE *dic = fopen(dictionary, "r");
    if (dic == NULL)
    {
        printf("Cound not open %s.\n", dictionary);
        return false;
    }

    char buffer[LENGTH + 1];

    while (fscanf(dic, "%s", buffer) != EOF)
    {
        // create a temporary node
        node *temp = malloc(sizeof(node));

        strcpy(temp->word, buffer);

        // implement hash function to get the index
        int index = hash(buffer);
        // if the corresponding index in hashtable is empty, assign it to the temp node
        if (table[index] == NULL)
            table[index] = temp;

        // else append temp to the start of the linked list
        else
        {
            temp->next = table[index];
            table[index] = temp;
        }
        dic_size++;
    }
    fclose(dic);
    return true;
}

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

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    // iterate through hashtable
    for (int i = 0; i < N; i++)
    {
        // set pointer to head of list
        node *cursor = table[i];

        // traverse list
        while (cursor != NULL)
        {
            node *temp = cursor;
            cursor = cursor->next;
            free(temp);
        }
        free(cursor);
    }
    return true;
}

Any help would be appreciated.

2

You are getting that error because in your 'load' function, you are inicializing the value 'next' here: temp->next = table[index]; inside an 'if' condition. If you also set temp->next to NULL after you declare it, you'll be good to go.

2
  • Minor edit for clarity. ;-) But right on target. Calloc instead of malloc would do the job too.
    – Cliff B
    May 14 '20 at 18:35
  • Total beginner here. I'm just here to learn. Feel free to edit any of my answers, as you seem to be one of the most experienced people around here. For furture correcness, what was your correction in my answer? Did you add the word "also"?
    – Tritum
    May 15 '20 at 7:49

You must log in to answer this question.

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