0

Thank you in advance for taking a look at my code.

I have been getting this error below:

==4734== 8,011,640 bytes in 143,065 blocks are indirectly lost in loss record 1 of 2
==4734==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4734==    by 0x4012A8: load (dictionary.c:83)
==4734==    by 0x4009F4: main (speller.c:40) 

It is telling me there is an issue with my load function related to malloc. I have been trying to free it within my load function but it didn't fix the issue but created more issues. Somehow my problem was fixed when I changed my size function.

Originally, my size function is to go to each word in the hashtable and count each word. please see below:

unsigned int size(void)
{
    unsigned int words = 0;
    for (int i = 0; i < 26; i++)
    {
        while (table[i] != NULL)
        {
            table[i] = table[i]->next;
            words++;
        }

    }

    return words;
}

I had to change the function and create a counter from load() and let size() return that value. This fixed the memory leak which got me super confused. What was wrong with my size function?

Below is the code before it was fixed.

#include <stdbool.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 = 26;

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    char *lowerWord = calloc(strlen(word)+1,sizeof(char));

    for (int i =0; word[i] != '\0'; i++)
    {
        lowerWord[i] = tolower(word[i]);
    }

    node *tmp;
    int position = hash(word);
    tmp = table[position];

    if (tmp == NULL)
    {
        return false;
    }

    while (tmp != NULL)
    {
        if (strcmp(tmp->word, lowerWord) == 0)
        {
            free(lowerWord);
            return true;
        }
        else
        {
            tmp = tmp->next;
        }
    }

    free(lowerWord);
    return false;

}

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

// Loads dictionary into memory, returning true if successful else false

bool load(const char *dictionary)
{
    FILE *dic;
    node *p, *prev;
    char *word = malloc(45 * sizeof(char)+1);
    dic = fopen(dictionary, "r");
    int position = 0;

    if (dic == NULL)
    {
        return false;
    }

    while (fscanf(dic, "%[^\n]\n", word) != EOF)
    {
        position = hash(word);
        p = malloc(sizeof(node));
        strcpy(p->word, word);
        p->next = NULL;

        if (table[position] == NULL)
        {
            table[position] = p;
        }
        else
        {
            prev->next = p;
        }
        prev = p;
    }

    free(word);
    fclose(dic);

    return true;
}



// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    unsigned int words = 0;
    for (int i = 0; i < 26; i++)
    {
        while (table[i] != NULL)
        {
            table[i] = table[i]->next;
            words++;
        }

    }

    return words;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    node *tmp;
    for (int i = 0; i < 26; i++)
    {
        while (table[i] != NULL)
        {
            tmp = table[i];
            table[i] = table[i]->next;
            free(tmp);
        }
    }


    for (int i = 0; i < 26; i++)
    {
        if (table[i] != NULL)
        {
            return false;
        }
    }
    return true;

}

Thank you.

1

This number 143,065 from valgrind is 26 less than the number of words in the (large) dictionary. Which, not coincidentally, is the number of elements in table.

This table[i] = table[i]->next "loses" all the nodes except the last, therefore they won't get freed in unload.

1
  • Thank you for the answer. This was a great help. – NgKen0995 Apr 28 '20 at 2:13

You must log in to answer this question.

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