0

after almost 2 month of working I am finishing the pset5 but... I get memory leaks. valgrind plus help50 is giving me this:

Looks like you're trying to access 8 bytes of memory that isn't yours? Did you try to index into an array beyond its bounds? Take a closer look at line 177 of dictionary.c.

I looked a lot in net about this but I still do not get what is wrong. Here is the code around line 177

//recurcive freeing
void unloading(node *s)
{
    for(int i = 0; i < 27; i++)
    {
        if(s -> children[i] != NULL)
        {
            unloading(s -> children[i]);
        }
    }
    free(s);
}

for me it should work well so I will put the full code here:

    // Implements a dictionary's functionality

#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include "dictionary.h"


//define the node type and give it a name - node
    typedef struct node
    {
        bool is_word;
        struct node *children[27];
    }
    node;

//function that will make for us nodes
void nodeing(int place);

//function will free all allocated memory in this node up to selected node
void unloading(node *s);

//function will establish place in the array by the converting of letter to number(a=0, b=1 etc. ' = 26)
//it words also with the uppercases
int indexing(char k);


//int for words to size
int number_of_words = 0;

 //creating the root of our trie with the empty pointers and flag for load
node *root, *current;

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


        //getting all the letters to the lowercase so we can compare them with dictionary structure loaded - thit is done in indexing function
        for(int h = 0; h < strlen(word); h++)
        {

                //creating the pointer to the current cheching letter. at 1st we start with root
                node *currentCheck = root;

                //establishing the place in the array
                int indexCh = indexing(word[h]);

                //checking the word if it is true or not (by the last letter match the trie structure
                //[is_word true and has pointer on the good place.)
                if(h != (strlen(word) - 1))
                {
                    if(currentCheck -> children[indexCh] != NULL)
                        currentCheck = currentCheck -> children[indexCh];

                    else
                        return false;

                }
                //checking if the letter in word is the structure
                else
                {
                    if(currentCheck -> is_word == true && currentCheck -> children[indexCh] != NULL)
                        return true;

                    else
                        return false;
                }

        }
        printf("something is not right - have not succed for any else if condition!");
        return false;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    root = malloc(sizeof(node));
    root -> is_word = false;
    for (int i = 0; i < 27; i++)
    {
        root -> children[i] = NULL;
    }


    //open to read and then check if the dictionary is openning
    FILE *fp_dictionary = fopen(dictionary, "r");
    if (fp_dictionary == NULL)
    {
        printf("Could not load the dictionary.");
        return false;
    }

    //create a buffer for a loaded word to use it by function fscaf
    char *word_to_load = malloc((LENGTH + 1) * sizeof(char));

    //getting strings from the file(here dictionary) one by one by the help of fscanf until the file finishes
    while(fscanf(fp_dictionary , "%s", word_to_load) != EOF)
    {
        //creating the pointer to the current node used. at 1st we start with root
        current = root;

        //adding letters to the scructure
        for (int k = 0; k < strlen(word_to_load); k++)
        {
            //creating an index (place in the array) intiger
            int index = indexing(word_to_load[k]);

            //condition for the last letter in the word(and one letter words) loaded
            if(k == (strlen(word_to_load) - 1))
            {
                current -> is_word = true;
                nodeing(index);
                number_of_words++;
            }


            else
            {
                if(current -> children[index] != NULL)
                current = current -> children[index];

                else
                nodeing(index);
            }
        }

    }
    free(word_to_load);
    free(current);
    fclose(fp_dictionary);
    return true;
}


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

    return number_of_words;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    // TODO
    unloading(root);
    return true;

}


//my functions:

//making a node
void nodeing(int place)
{
    node *new_node = malloc(sizeof(node));
    for (int i = 0; i < 27; i++)
    {
        new_node -> children[i] = NULL;
    }
    current -> children[place] = new_node;
    current = new_node;
}

//recurcive freeing
void unloading(node *s)
{
    for(int i = 0; i < 27; i++)
    {
        if(s -> children[i] != NULL)
        {
            unloading(s -> children[i]);
        }
    }
    free(s);
}

int indexing(char k)
{
    if(k == '\'')
        return 26;

    else
    {
        return (int)tolower(k) - 97;
    }
}
1

unloading is fine. load isn't.

free(current); refers to a node that's installed in your trie, so you may not free it. Remove that line.

current -> is_word = true; is the only thing that should be executed conditionally for the last character, the rest should stay the same, and is_word should be set only after you have updated current.

Also, you don't seem to initialise is_word in nodeing.

And it's a weird construction to have a global traversal pointer, as is it that you pass an index to nodeing. I'd have my node alloc/initialise function return a new node, and include it in the trie only in the load function. That way, I can use it for both the root node and other nodes, not having the same code twice.

3
  • thank you, when i was posting it i saw also nodeing and code below the root but I was so frustrated that I have not changed it. RIght now the steam went down so I will use your advice and I hope I will get it ;) – koko loko Jul 24 '18 at 19:22
  • thank you it has helped me:) I have one more question because my check values does not match with the answers. Could you check the check function if everything is ok because i cannot find anything ;( ? – koko loko Jul 25 '18 at 9:15
  • Both, the current->is_word = true in load, and the currentCheck->is_word == true should happen after the for loop. You are adding the "is word" property to the parent of the node it is supposed to go. Like in "cat", you are putting it at the "ca" node. – Blauelf Jul 25 '18 at 10:00

You must log in to answer this question.

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