0

I am having problem in my unload. While running valgrind it shows no leaks, but the program wont acquiesce check50. Here is the unload function:

//free the memory

bool freenode(node *first)
{
    //iterate over the entire trie bloaks
    for(int i = 0 ; i<27;i++)
    {
        //Look for the terminating block
        if(first->children[i] != NULL)
        {
            freenode(first->children[i]);
        }

    }
    free (first);

    return true;
}
//unloads the dictionary
bool unload(void)
{
        return freenode(root);
}

The complete code:-

// Implements a dictionary's functionality

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <crypt.h>

#include "dictionary.h"

//Setting up a counter for the number of misspelled words
int counter = 0;

//defining a structure for a node
typedef struct node
{
    bool isword;
    struct node *children[27];
}
node;

//defining the base node
node *root = NULL;

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    //the travelling pointer first pointing to the root
    node *first = root;

    //goes through the entire word letter by letter
    for ( int i = 0 ; i < strlen(word) ; i++)
    {
        //reads the letter of the word and converts from ascii value to a 
          regular int with a being read as 0
        int index = tolower(word[i]) - 'a';
        //the words starting with apostraphies are groued in the 26th index
        if(word[i] == '\'')
        {
            index = 26;
        }
        //if no such word with the starting alphabet was found earlier, 
            create a new root
        if(first->children[index] == NULL)
        {
            first = root;
            return false;
        }
        //go there
        first = first->children[index];
    }
    //return true for the found word
    if(first->isword)
    {
        first = root;
        return true;
    }
    else
    {
        first = root;
        return false;
    }
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{

    //try to open the dictionary file
    FILE* file = fopen(dictionary, "r");
    if ( file == NULL)
    {
        printf("dictionary could not be opened");
        unload();
        return 1;
    }

    //start with the base pointer of the trie
    root = calloc(27,sizeof(node));
    node *first = root;

    char word[LENGTH +1];

    //reading the dictionary for words
    while(fscanf(file, "%s",word) != EOF)
    {
        counter++;
        //iterate over the word
        for (int i = 0 ; i<strlen(word); i++)
        {
            //setting the alphabet as an int to categorize in the trie
            int index = tolower(word[i]) - 'a';

            //apostrophe case
            if(word[i] == '\'')
            {
                index = 26;
            }
            //check if the branch of the trie has been initiated previously
            if(first->children[index] == NULL)
            {
                node *newnode = calloc(1, sizeof(node));
                first->children[index] = newnode;
                first = newnode;
            }
            else
            {
                first= first->children[index];
            }
        }
        first->isword = true;
        first = root;
    }
    //close the file
    fclose(file);
        return true;

}

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

// Unloads dictionary from memory, returning true if successful else false

bool freenode(node *first)
{
    for(int i = 0 ; i<27;i++)
    {
        if(first->children[i] != NULL)
        {
            freenode(first->children[i]);
        }
        //first->children[i] = NULL;
    }
    // first = NULL;
    free (first);

    return true;
}

bool unload(void)
{
    //
    return freenode(root);
}
  • What is check50 reporting exactly? – Cliff B Jul 23 '18 at 16:23
  • valgrind tests failed :( – Kushagra Chawda Jul 23 '18 at 17:31
1

The code looks correct (assuming children is a node[27]).

Either that's not the code you submitted, or you have another problem, most likely uninitialised memory (memory by malloc may initially contain anything, so initialise it or use calloc instead of malloc to initialise to zero), or a double free. For example, in load or check, you should probably have no free, and having one would likely cause a double free, freeing a node twice.

| improve this answer | |
  • All good guesses, but all would lead to either a runtime error or a memory leak, both of which he says aren't happening. I really want to see the actual output from check50 - maybe a link to the check50 results? – Cliff B Jul 23 '18 at 17:05
  • the problem persists with calloc. I have uploaded the complete code too. – Kushagra Chawda Jul 23 '18 at 17:40
  • Seems like a miracle, but i callocd in both check and load, the problem seems to evaporate. The code as expected works just fine but also passess check 50. Thankyou so much people, i think i am crying – Kushagra Chawda Jul 23 '18 at 17:53
  • root is a single node, it does not need space for 27. – Blauelf Jul 23 '18 at 20:48
  • noted. Thanks for pointing the error – Kushagra Chawda Jul 24 '18 at 14:34

You must log in to answer this question.

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