0

For my Pset4 Speller, the unload() function is not working. I have tracked the problem to the free() function not working, but cannot get further than that. Could someone offer me any pointers please? (Also please not in hexadecimal:) Also, thank you Blauelf for the corrections. Any more would be really helpful.

Code:

//Implements a dictionary's functionality
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dictionary.h"

//Represents number of children for each node in a trie
#define N 27

//Initializes global variable for trie size
int counter = 0;

//Represents root of a trie
trie *root;

//Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    //Opens dictionary
    FILE *file = fopen(dictionary, "r");
    if (!file)
    {
        return false;
    }
    root = calloc(1, sizeof(trie));
    trie *insert = root;
    trie *insert2 = root;
    //Allocates a pointer to insert a word
    for (char c = fgetc(file); c != EOF; c = fgetc(file))
    {
        if (c == '\n')
        {
            insert->is_word = true;
            counter++;
            insert = root;
            insert2 = root;
        }
        else
        {
            int indexed;
            if (c == '\'')
            {
                indexed = 26;
            }
            else if (isalpha(c))
            {
                c = toupper(c);
                indexed = c - 65;
            }
            else
            {
                return false;
            }
            insert2 = insert->next[indexed];
            if (!insert2)
            {
                insert2 = calloc(1, sizeof(trie));
                if (!insert2)
                {
                    return false;
                }
                insert->next[indexed] = insert2;
                insert = insert2;
            }
            else
            {
                insert = insert2;
            }
        }
    }
    return true;
}

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

//Returns true if word is in dictionary else false
bool check(const char *word)
{
    trie *search = root;
    for (int i = 0, length = strlen(word); i <= length; i++)
    {
        int indexed;
        //Indexes char if not newline, checks word ending if it is
        if (word[i] != '\n')
        {
            if (word[i] == '\0')
            {
                if (search->is_word)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                if (word[i] == '\'')
                {
                    indexed = 26;
                }
                else if (isalpha(word[i]))
                {
                    char c = toupper(word[i]);
                    indexed = c - 65;
                }
                else
                {
                    return false;
                }
                trie *search2 = search->next[indexed];
                if (!search2)
                {
                    return false;
                }
                search = search2;
            }
        }
        else
        {
            return false;
        }
    }
    return true;
}

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

void deload(trie *removing)
{
    for (int i = 0; i < N; i++)
    {
        if (removing->next[i] != NULL)
        {
            deload(removing->next[i]);
        }
    }
    //Since all the other pointers point to NULL, you can free the pointer
    free(removing);
}

Error: enter image description here enter image description here

1 Answer 1

1

Please note that malloc makes no guarantee on the content of the allocated memory. Use calloc (which zeroes the range, in this case exactly what we want), memset or similar, or initialise the fields manually.

In your unload routine, who do you think sets root to NULL? free just declares a memory range as no longer allocated, it has no idea where pointers still exist. So remove the check from unload, and just return true;

edit: Just missed another leak: You fopen, but never fclose the dictionary file. The FILE structure is allocated in fopen, and will be freed in fclose, after handling all the background stuff (the structure corresponds to an open file after all).

7
  • Thank you so much Blauelf, really helped. At least my code now only has one error!
    – AK2150
    Commented Apr 9, 2019 at 4:37
  • calloc(0,0)? Why would you allocate anything (of size 0?) if you want to free? With that reassignment, you keep the code from working.
    – Blauelf
    Commented Apr 9, 2019 at 7:06
  • The reason for setting free to calloc(0, 0) was to free it. I only added that line of code in an attempt to return the memory back. Because it does not work, I changed the code to "removing = 0x0;" but it still did not work. I even tried removing that line, but it still did not work. So is there no way to give the memory back? Thank you Blauelf for the help, any more redirects would be greatly appreciated.
    – AK2150
    Commented Apr 9, 2019 at 15:28
  • PS I also tried to remove the free(removing); line, but it still did not work.
    – AK2150
    Commented Apr 9, 2019 at 15:36
  • This makes no sense at all. removing contains a pointer to a node to remove. Then you throw away the value and replace it with something else. Just free(removing);, without any removing= line.
    – Blauelf
    Commented Apr 9, 2019 at 16:08

You must log in to answer this question.

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