0

I have mostly completed the implementation, other than being able to free the memory. When I run my program through valgrind, lines 65, 66 and 103 are flagged even though I have freed the memory of all of these pointers. I put a "<<" on these 3 lines. Please help. Thanks!

/**
 * Implements a dictionary's functionality.
 */

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

#include "dictionary.h"
#include "storage.h"

/**
 * Returns true if word is in dictionary else false.
 */
storage *createNode(char a){
    storage *n = malloc(sizeof(storage));
    n->c = a;
    n->nextList = n->nextElement = NULL;
    n->isWord = false;
    return n;
}

void addNode(char c, storage *a){
    storage *n = createNode(c);
    while (a->nextElement != NULL){
        a = a->nextElement;
    }
    a->nextElement = n;
    n->isWord = false;
}
//initial is changed
storage *findNode(storage *initial, char c){
    while(initial->c != c){
        if(initial->nextElement == NULL){
            return NULL;
        }
        initial = initial->nextElement;
    }
    return initial;
}

void frees(storage *current){
    //printf("FREEING\n");
    if(current->nextList != NULL){
        frees(current->nextList);
    }
    if(current->nextElement != NULL){
        frees(current->nextElement);
    }
    free(current);

}

storage *start = NULL;
int num = 0;
bool check(const char *word)
{
    char theWord[46];
    strcpy(theWord, word);
    for(int i=0; theWord[i] != '\0'; i++){
        theWord[i] = tolower(theWord[i]);
    }
    storage *buffer = malloc(sizeof(storage)); <<
    storage *current = malloc(sizeof(storage)); <<
    current = start;
    /*if(current == NULL){
        printf("its NUll!");
    }*/
    for(int i = 0; theWord[i] != '\0'; i++){
        buffer = findNode(current, theWord[i]);
        if(buffer == NULL){
            return false;
        }
        else{
            current = buffer;
            if(current->nextList != NULL){
                current = current->nextList;
            }
            else{
                return false;
            }
        }
    }
    if(current->isWord){
        //printf("check for %s is a success!",theWord);
        return true;
    }
    else{
        return false;
    }
    free(buffer);
    free(current);
}

/**
 * Loads dictionary into memory. Returns true if successful else false.
 */

bool load(const char *dictionary)
{
    storage *buffer = malloc(sizeof(storage)); <<
    start = createNode('a');
    //bool cnew = false;
    //printf("a");
    FILE *file = fopen(dictionary,"r");
    if(file == NULL){
        printf("Could not open dictionary\n");
        return false;
    }
    //storage **spare = malloc(sizeof(storage **));
    //printf("b");
    storage *current = start;
    for (int c = fgetc(file); c != EOF; c = fgetc(file)){
        //printf("char is %c ",c);
        /*if(cnew && (isalpha(c) || c == '\'')){
            current->nextList = createNode(c);
            current = current->nextList;
            cnew = false;
        }*/
        if (isalpha(c) || c == '\''){
            buffer = findNode(current, c);
            if(buffer != NULL){
                current = buffer;
                //printf("findNode successful , %c %c\n",current->c,c);
                if(current->nextList != NULL){
                    current = current->nextList;
                    //printf("c\n");
                }
                else{
                    //cnew = true;
                    current->nextList = createNode('a');
                    current = current->nextList;
                    //printf("d\n");
                }

            }
            else{
                addNode(c,current);
                while(current->nextElement != NULL){
                    current = current->nextElement;
                }
                current->nextList = createNode('a');
                current = current->nextList;
                //printf("e\n");
            }
        }
        else{
            current->isWord = true;
            current = start;
            num++;
            //current = current->nextElement;
            //printf("f\n");
            /*if(current->nextList == NULL){
                printf("null\n");
            }*/
            /*current = current->nextElement;
            current = current->nextList;
            printf("g\n");
            printf("%c",current->c);//a
            current = current->nextElement;
            printf("%c",current->c);//c
            current = current->nextList;
            printf("%c",current->c);//a
            current = current->nextList;
            printf("%c",current->c);//a
            current = current->nextElement;
            printf("%c",current->c);//t*/

            //cnew = false;

        }
    }
    //printf("g");
    //print(start);
    free(buffer);
    return true;
}

/**
 * Returns number of words in dictionary if loaded else 0 if not yet loaded.
 */
unsigned int size(void)
{
    if(start == NULL){
        return 0;
    }
    else{
        //printf("number of words in %d",num);
        return num;
    }

}

/**
 * Unloads dictionary from memory. Returns true if successful else false.
 */
bool unload(void)
{
    frees(start);
    return true;
}

Below is the valgrind message

==5051== 
==5051== HEAP SUMMARY:
==5051==     in use at exit: 1,905,112 bytes in 59,518 blocks
==5051==   total heap usage: 770,082 allocs, 710,564 frees, 24,643,696 bytes allocated
==5051== 
==5051== 32 bytes in 1 blocks are possibly lost in loss record 1 of 5
==5051==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5051==    by 0x40120A: check (dictionary.c:66)
==5051==    by 0x400C61: main (speller.c:113)
==5051== 
==5051== 32 bytes in 1 blocks are definitely lost in loss record 2 of 5
==5051==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5051==    by 0x4012EA: load (dictionary.c:103)
==5051==    by 0x400904: main (speller.c:41)
==5051== 
==5051== 952,224 bytes in 29,757 blocks are definitely lost in loss record 4 of 5
==5051==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5051==    by 0x40120A: check (dictionary.c:66)
==5051==    by 0x400C61: main (speller.c:113)
==5051== 
==5051== 952,256 bytes in 29,758 blocks are definitely lost in loss record 5 of 5
==5051==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5051==    by 0x4011FA: check (dictionary.c:65)
==5051==    by 0x400C61: main (speller.c:113)
==5051== 
==5051== LEAK SUMMARY:
==5051==    definitely lost: 1,904,512 bytes in 59,516 blocks
==5051==    indirectly lost: 0 bytes in 0 blocks
==5051==      possibly lost: 32 bytes in 1 blocks
==5051==    still reachable: 568 bytes in 1 blocks
==5051==         suppressed: 0 bytes in 0 blocks
==5051== Reachable blocks (those to which a pointer was found) are not shown.
==5051== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5051== 
==5051== For counts of detected and suppressed errors, rerun with: -v
==5051== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)

Helping with...                                                                                                                                                     

==5051== 32 bytes in 1 blocks are definitely lost in loss record 2 of 5
==5051==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5051==    by 0x4012EA: load (dictionary.c:103)
==5051==    by 0x400904: main (speller.c:41)

Looks like your program leaked 32 bytes of memory. Did you forget to free memory that you allocated via malloc? Take a closer look at line 103 of
dictionary.c.
1

Here you allocate some memory:

    storage *buffer = malloc(sizeof(storage));

Here you throw away the pointer, and assign something else, losing any way to free that memory:

        buffer = findNode(current, theWord[i]);

Here you allocate some memory:

    storage *current = malloc(sizeof(storage));

And on the next line, you throw away the pointer:

    current = start;

And I'm really glad the code

    free(buffer);
    free(current);

won't ever run because it's behind a return statement.

And again,

    storage *buffer = malloc(sizeof(storage));

allocates memory you lose the pointer for on

            buffer = findNode(current, c);
1
  • Omg wow thanks so much dude
    – Aryan Jain
    Dec 14 '17 at 14:23

You must log in to answer this question.

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