0

I've successfully implemented the dictionary and it fully works (already submitted and got 100/100). But when I run valgrind I get9911215 errors from 6 contexts. I really don't know what that means or how to fix this. Can someone help?

From Valgrind:

==3598== Memcheck, a memory error detector
==3598== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3598== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3598== Command: ./speller texts/ralph.txt
==3598== 
==3598== Conditional jump or move depends on uninitialised value(s)
==3598==    at 0x401355: load (dictionary.c:111)
==3598==    by 0x40097D: main (speller.c:40)
==3598==  Uninitialised value was created by a heap allocation
==3598==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3598==    by 0x401238: load (dictionary.c:77)
==3598==    by 0x40097D: main (speller.c:40)
==3598== 

MISSPELLED WORDS

==3598== Conditional jump or move depends on uninitialised value(s)
==3598==    at 0x401198: check (dictionary.c:51)
==3598==    by 0x400D07: main (speller.c:112)
==3598==  Uninitialised value was created by a heap allocation
==3598==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3598==    by 0x401366: load (dictionary.c:113)
==3598==    by 0x40097D: main (speller.c:40)
==3598== 
Wiggum
==3598== Conditional jump or move depends on uninitialised value(s)
==3598==    at 0x401461: unloadNode (dictionary.c:148)
==3598==    by 0x401478: unloadNode (dictionary.c:150)
==3598==    by 0x401478: unloadNode (dictionary.c:150)
==3598==    by 0x401478: unloadNode (dictionary.c:150)
==3598==    by 0x401410: unload (dictionary.c:162)
==3598==    by 0x400E8C: main (speller.c:152)
==3598==  Uninitialised value was created by a heap allocation
==3598==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3598==    by 0x401366: load (dictionary.c:113)
==3598==    by 0x40097D: main (speller.c:40)
==3598== 
==3598== Conditional jump or move depends on uninitialised value(s)
==3598==    at 0x401461: unloadNode (dictionary.c:148)
==3598==    by 0x401478: unloadNode (dictionary.c:150)
==3598==    by 0x401478: unloadNode (dictionary.c:150)
==3598==    by 0x401410: unload (dictionary.c:162)
==3598==    by 0x400E8C: main (speller.c:152)
==3598==  Uninitialised value was created by a heap allocation
==3598==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3598==    by 0x401366: load (dictionary.c:113)
==3598==    by 0x40097D: main (speller.c:40)
==3598== 
==3598== Conditional jump or move depends on uninitialised value(s)
==3598==    at 0x401461: unloadNode (dictionary.c:148)
==3598==    by 0x401478: unloadNode (dictionary.c:150)
==3598==    by 0x401410: unload (dictionary.c:162)
==3598==    by 0x400E8C: main (speller.c:152)
==3598==  Uninitialised value was created by a heap allocation
==3598==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3598==    by 0x401366: load (dictionary.c:113)
==3598==    by 0x40097D: main (speller.c:40)
==3598== 
==3598== Conditional jump or move depends on uninitialised value(s)
==3598==    at 0x401461: unloadNode (dictionary.c:148)
==3598==    by 0x401410: unload (dictionary.c:162)
==3598==    by 0x400E8C: main (speller.c:152)
==3598==  Uninitialised value was created by a heap allocation
==3598==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3598==    by 0x401238: load (dictionary.c:77)
==3598==    by 0x40097D: main (speller.c:40)
==3598== 

WORDS MISSPELLED:     1
WORDS IN DICTIONARY:  143091
WORDS IN TEXT:        20
TIME IN load:         3.82
TIME IN check:        0.00
TIME IN size:         0.00
TIME IN unload:       10.89
TIME IN TOTAL:        14.71

==3598== 
==3598== HEAP SUMMARY:
==3598==     in use at exit: 0 bytes in 0 blocks
==3598==   total heap usage: 367,084 allocs, 367,084 frees, 82,227,504 bytes allocated
==3598== 
==3598== All heap blocks were freed -- no leaks are possible
==3598== 
==3598== For counts of detected and suppressed errors, rerun with: -v
==3598== ERROR SUMMARY: 9911215 errors from 6 contexts (suppressed: 0 from 0)

My code in dictionary.c

/**
 * CS50 - PSET5 - user: linhobru
 * Implements a dictionary's functionality.
 */

#include <stdbool.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/time.h>

#include "dictionary.h"

#define ALPHABETSIZE 27

typedef struct node
{
    bool is_word;
    struct node *children[ALPHABETSIZE];
} 
node;

node *root = NULL;

int num_of_words = 0;

/**
 * Returns true if word is in dictionary else false.
 */
bool check(const char *word)
{

    node* next = root;

    int k = ALPHABETSIZE;

    for (int i = 0, len = strlen(word); i < len ; i++) // until (char) word[i] == '\0' 
    {
        // verify letter and transform in index from 0 to 26
        if (word[i] == '\'')
        {
            k = ALPHABETSIZE - 1;
        }
        else if (isalpha(word[i]))
        {
            k = tolower(word[i]) - 97;
        }

        if (next->children[k] == NULL)
        {
            return false;
        }
        else
        {
        next = next->children[k];   
        }

    }
    return next->is_word;
}

/**
 * Loads dictionary into memory. Returns true if successful else false.
 */
bool load(const char *dictionary)
{
    FILE *dict = fopen(dictionary, "r");
    if (dict == NULL)
    {
        return false;
    }

    char word[LENGTH];

    root = malloc(sizeof(node));
    if (root == NULL)
    {
        unload();
        fclose(dict);
        return false;
    }

    while (fscanf(dict,"%s", word) != EOF)
    {
        node* now = root;
        int k = ALPHABETSIZE;

        for (int i = 0; word[i] != '\0'; i++) 
        {
            // verify letter and transform in index from 0 to 26
            if (word[i] == 39) // '\''
            {
                k = ALPHABETSIZE - 1;
            }
            else if (word[i] >= 97 && word[i] <= 122)
            {
                k = word[i] - 97;
            }
            /* else if (word[i] >= 65 && word[i] <= 90)
            {
                k = word[i] % 65;
            }*/ 
            else
            {
                fclose(dict);
                return false;               
            }

            if (now->children[k] == NULL)
            {
                node* new_node = malloc(sizeof(node));
                now->children[k] = new_node;
            }

            now = now->children[k];

            if (word[i + 1] == '\0')
            {
                now->is_word = true;
            } 


        }

        num_of_words++;
    }
    fclose(dict);
    return true;
}

/**
 * Returns number of words in dictionary if loaded else 0 if not yet loaded.
 */
unsigned int size(void)
{
    return num_of_words;
}
/**
 * Receives root at first and then each children to free.
 */
void unloadNode(node* next)
{
    // call unloadNode on every node in this node's children
    for(int i = 0; i < ALPHABETSIZE; i++)
    {
        if(next->children[i] != NULL)
        {
            unloadNode(next->children[i]);
        }
    }

    // once the children nodes are freed, free this node
    free(next);
}
/**
 * Unloads dictionary from memory. Returns true if successful else false.
 */
bool unload(void)
{
    unloadNode(root);
    return true;
}
0

When you allocate memory for a node, you can't be sure that each of the pointers in children[] points to NULL, as you so surely check for later. You will have to explicitly set them to NULL. Or you can also take a look at calloc(), which not only allocates the memory, but initializes it to the default values too.

You must log in to answer this question.

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