1

I'm running valgrind on my speller for a hashtable. One of the errors I get, I'm not sure I understand is

uninitialised value was created by a heap allocation

==3079==  Uninitialised value was created by a heap allocation
==3079==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3079==    by 0x401137: load (dictionary.c:82)
==3079==    by 0x400964: main (speller.c:40)
==3079=

I beleive it's because I am allocating space in memory for a pointer that does not have a value -- since it has not been initialized yet? I'm note. Below is my load function where I'm getting the error.

If I initialize the ptr node -- what do I initiialize it to? I know if it's NULL, it will exit the function, which I don't want.

In the code below the error [line 82] is:

new_node = (struct node *) malloc(sizeof(node));

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // Initialize hash table
    for (int i = 0; i < N; i++)
    {
        hashtable[i] = NULL;
    }

    // Open dictionary
    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        unload();
        return false;
    }

    // Buffer for a word
    char word[LENGTH + 1];

    // Insert words into hash table
    while (fscanf(file, "%s", word) != EOF)
    {
        // TODO
        countWords++;
        //create node
        struct node * new_node;
        //create a new node anytime new word
        //create a node and allocate memory for each word

      //THIS IS WHERE THE ERROR IS !!!! 
      new_node = (struct node *) malloc(sizeof(node));
        //if empty...
        if (new_node == NULL)
        {
            //speller quits
            unload();
            return false;
        }

        //copy word into node
        strcpy(new_node->word, word);

        //get location of word to go in hashtable by hashing value
        int index = hash(word);

        //put word in that location if nothing there
        if(hashtable[index] == NULL)
        {
            //QUESTION: is head in array or at end of linked-list?
            hashtable[index] = new_node;
        }

        //we need to link it to last node
        else
        {
           struct node * head = (struct node *) malloc(sizeof(node));
           head = hashtable[index];
           new_node -> next = head->next; //I may not be assigning this correct
           head->next = new_node;

        }
    }
    //printNumber();//header);
   // free(new_node);
    // Close dictionary
    fclose(file);

    // Indicate success
    return true;
}

Thanks for your advice!

2 Answers 2

3

Your new_node -> next is not initialised if it's the first node of a list. malloc allocates memory, but does not guarantee any content, you will get whatever was there before (likely all zeros if your programme just got this memory from the operating system, so your code would probably work in this case, pick a more dynamic scenario with nodes added and deleted all the time, and it won't).

You are inserting new nodes second place for an existing list. You could use one common code if it was the first one, by setting up your new node's next to point to the old list head, and then have the list head pointer point to your new node.

1
  • Thank you so much!
    – C0G1T0
    Commented Jun 12, 2023 at 10:44
2

Blauelf is right. I had a similar problem which was being caused by not initialising the next field in the first node I was adding to the hash table. I fixed it by assigning NULL to the next field in my new node when I added it to an empty element in the hash table. The final code:

    //add first node to hashtable element
    if (table[h] == NULL)
    {
        n->next = NULL;
        table[h] = n;
        words++;
    }
    //add new node to hashtable element with existing elements
    else
    {
        n->next = table[h];
        table[h] = n;
        words++;
    }

You must log in to answer this question.

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