0

I've been trying to read other questions on stack exchange about it and do research on it but I really couldn't find a solution for my unload problem. It doesn't seem to unload much. I tried a lot of different ways to free the memory but every time it leaks a crazy amount of memory. Might something be wrong with any of the other functions?

Here's the load function:

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // array to store the word letter by letter including \0
    char words[LENGTH + 1];

    // open dictionary file and read from it
    FILE *dfile = fopen(dictionary, "r");
    if (dfile == NULL)
    {
        return 1;
    }

    // scan words from dictionary into array until EOF reached
    while(fscanf(dfile, "%s", words) == 1)
    {
        // for every word found, create a new node
        n = malloc(sizeof(node));
        if (n != NULL)
        {
            //  copy the word found into the node and set pointer to NULL
            strcpy(n -> word, words); 
            n -> next = NULL;
        }

        // add to word counter
        word_count++;

        // put word into hash function
        int index = hash (n -> word);
    
        // check if list is empty
        if (table[index] == NULL)
        {
            table[index] = n;
        }
    
        // if list is not empty, put new node in beginning of list
        else
        {
           n -> next = table[index];
           table[index] = n;
        }
   
    }
    // end of function
    return true;
}

Here's the check function, where the error seems to be:

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    char new_word[strlen(word) + 1];

    for (int i = 0, j = strlen(word); i <= j; i++)
    {
        new_word[i] = tolower(word[i]);
    }

    int index = hash (new_word);

    cursor = malloc(sizeof(node));
    if (cursor == NULL)
    {
        return 1;
    }
    cursor = table[index];

    while (cursor != NULL)
    {
       if (strcasecmp (cursor -> word, new_word ) == 0)
       {
           return true;
       }
    
       else cursor = cursor -> next;
    }
   return false;
}

Unload function: I had set N (hash table size) to 2'000.

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

    for (int i = 0; i < N; i++)
    {
        node *curs = table[i];
    
        while (curs != NULL)
        {
            node *temp = curs->next;
            free(curs);
            curs = temp;
        }
    }
    free(cursor);
}

Here's the valgrind report. This is with the Lalaland.txt. It points to line 47 which is cursor = malloc(sizeof(node)); in the check function.

==2472== HEAP SUMMARY:
==2472==     in use at exit: 994,888 bytes in 17,757 blocks
==2472==   total heap usage: 160,852 allocs, 143,096 frees, 9,017,752 bytes allocated
==2472== 
==2472== 552 bytes in 1 blocks are still reachable in loss record 1 of 2
==2472==    at 0x4C2FB0F: malloc (in     /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2472==    by 0x5258E49: __fopen_internal (iofopen.c:65)
==2472==    by 0x5258E49: fopen@@GLIBC_2.2.5 (iofopen.c:89)
==2472==    by 0x4012BE: load (dictionary.c:90)
==2472==    by 0x4009B4: main (speller.c:40)
==2472== 
==2472== 994,336 bytes in 17,756 blocks are definitely lost in loss record 2 of 2
==2472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2472==    by 0x40113E: check (dictionary.c:47)
==2472==    by 0x400CD9: main (speller.c:112)
==2472== 
==2472== LEAK SUMMARY:
==2472==    definitely lost: 994,336 bytes in 17,756 blocks
==2472==    indirectly lost: 0 bytes in 0 blocks
==2472==      possibly lost: 0 bytes in 0 blocks
==2472==    still reachable: 552 bytes in 1 blocks
==2472==         suppressed: 0 bytes in 0 blocks
==2472== 
==2472== For counts of detected and suppressed errors, rerun with: -v
==2472== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

Asking for help...

==2472== 994,336 bytes in 17,756 blocks are definitely lost in loss record 2 of 2
==2472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2472==    by 0x40113E: check (dictionary.c:47)
==2472==    by 0x400CD9: main (speller.c:112)
Looks like your program leaked 994,336 bytes of memory. 
Did you forget to free memory that you allocated via malloc? 
Take a closer look at line 47 of dictionary.c.
1

Simple enough. The first line in unload() is return true;. That terminates processing of the unload function immediately and returns control to main.

In check(), cursor has memory allocated to it with a call to malloc. It then immediately gets reassigned, so every time check is called, this memory is lost. It should just immediately set cursor to table[index]. Since cursor is only being used to traverse the existing memory in the tree, it does not need to have any new memory allocated to it.

Finally, did you remember to close all files that have been opened?

Programming note: It appears that the program has a global node pointer called cursor. Globals should only be created when absolutely necessary. In this pset, any cursors that are needed can all be created as local vars. There is at least one global var that's appropriate in this program.

If this answers your question, please click on the check mark to accept. Let's keep up on forum mainteance. ;-)

2
  • Wow, thanks a lot Cliff! That solved it all! I thought I read somewhere here on stackexchange about pset5 where someone mentions to use return true; in the beginning... guess it was the wrong choice. And thanks for the programming note, I used globals because I thought I'd need them in different functions but I didn't. – abbanator Aug 1 '20 at 21:39
  • You did, that was me. But you needed to read the context. The other person needed to work on the rest of the program before sorting out unload, so I told them to insert a return true statement temporarily. – Cliff B Aug 2 '20 at 3:48

You must log in to answer this question.

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