0

Upon writing unload, I get the following error

*** Error in `/home/ubuntu/workspace/pset5/speller/speller': double free or corruption (!prev): 0x0000000000603250 ***

In the GDB console, I get

Program received signal SIGABRT, Aborted.
0x00007ffff7a4bcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.

What am I doing wrong? Here is my code.

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

#include "dictionary.h"

#define MAX     27

typedef struct node
{
    bool is_word;
    struct node *children[MAX];

}node;

node *root, *travP, *nodeP;

/**
 *  Deletes nodes
 */
bool delete(node *target)
{
    for(int c = 0; c != MAX; c++ )
    {
        //if null pointer is reached
        if(target->children[c] == NULL)
        {
            //stop
        }
        //delete the rest of the list
        else
        {
            target = target->children[c];
            delete(target);
        }

        //free current node
        free(target);

    }

        if(target == NULL)
    {
        return true;
    }

    else
        return false;

}


/**
 * Returns true if word is in dictionary else false.
 */
bool check(const char *word)
{
    travP = root;
    //printf("%s\n", word);
    // TODO
    //for letter in word
    for( ; *word != '\0'; ++word)
    {
        //printf("%c", *word);

        int c = *word;

        if(isalpha(c) || (c == '\''))
        {
            if (c == '\'')
            {
                c = 26;
            }

            //convert a to the equivalent ascii value which will serve as the index 'c' in the array children
            else
            {
                c = tolower(c);
                c = c - 97;
            }

             //go to the corresponding element in children

             if (travP->children[c] == NULL)
             {
                  //if NULL, word is mispelled
                 return 0;
             }

             else
             {
                 //if not NULL, move to next letter
                 travP = travP->children[c];

             }


        }

        else
        {
            return 3;
        }

    }

    //Once at end of input word
    //check if is_word is true
    if(travP->is_word == 1)
    {
        return true;
    }

    else
    {
        return false;
    }

}

/**
 * Loads dictionary into memory. Returns true if successful else false.
 */
bool load(const char *dictionary)
{   
    int c;

    //open dictionary file
    FILE *dicp = fopen(dictionary, "r");
    //check for Null value
    if (dicp == NULL)
    {
        printf("Could not open dictionary %s\n", dictionary);
        return 1;
    }
    //int a;

    //pointer to the top of the trie
    root = calloc(1, sizeof(node));
    if(root == NULL)
        {
            return false;
            //return 2;
        }

    travP = root;

    //for every dictionary word, iterate through the trie
    for(c = fgetc(dicp); c != EOF; c = fgetc(dicp))
    {
        //if LF is hit, set word to true

        if (isalpha(c) || (c == '\''))
        { 

            //Each element in children corresponds to a different letter

            if (c == '\'')
            {
                c = 26;
            }

            //convert a to the equivalent ascii value which will serve as the index 'c' in the array children
            else
            {
                c = tolower(c);
                c = c - 97;
            }


            //printf("%c\n", c);

            //check if children[c] is null  
            if (travP->children[c] == NULL)
            {
                //if children[c]== NULL, malloc a new node.
                node *nodeP = calloc(1, sizeof(node));

                //have children[c] point to the new node
                travP->children[c] = nodeP; //Is this correct?

                //go down to that block of memory
                travP = travP->children[c];

                //I might need a recursive function. 

            }

            else
            {
                //if not NULL move to new node and continue
                travP = travP->children[c];
            }
        }

        //if at end of word, set is_word to true
        else
        {
            travP->is_word = 1;
            travP = root;
        }



    }

    //Free all malloced memory
    //free(nodeP);
    //free(root);

    fclose(dicp);

    //return true if load was successful
    if(c == EOF)
        return true;

    //return false if load was unsuccessful
    else
        return false;



}

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

/**
 * Unloads dictionary from memory. Returns true if successful else false.
 */
bool unload(void)
{
    //holder for the value of the delete function.
    bool list;

    //travel to the lowest possible node
    //free all pointers in children
    //backtrackupwards, freeing all elements in each children array
    //until you hit root node
    travP = root;

    list = delete(travP);

    return list;

}
0

My answer is based on the following posts. After the changes, unload now works just fine :)

  1. pset5 unload double free or corruption
  2. Problem in my unload function (double free or corruption)
  3. Unload function double free or corruption

I changed my delete and unload functions as follows:

bool delete(node *target)
{
    //target = root;

    for(int c = 0; c != MAX; c++ )
    {
        //if null pointer is reached
        if(target->children[c] == NULL)
        {
            //stop
        }
        //delete the rest of the list
        else
        {
            //target = target->children[c];
            delete(target->children[c]);

        }

    }
    //free current node
    free(target);

    /*

        if(target == NULL)
    {
        return true;
    }

    else
        return false;
        */

        return true;

}


bool unload(void)
{

    bool list;

    list = delete(travP);

    return list;

}

You must log in to answer this question.

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