Search code examples
cvalgrinddynamic-memory-allocation

Valgrind reporting lost bytes even after using free()


I have been trying a few things in C language after reading about memory allocation. Everything seemed to have been pretty soft and eye-catching, until I got stuck in this program. It works as intended but valgrind clearly states a whole different story. Here's my program:

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

#define NSTRINGS 3

int main()
{
    char **v = NULL;
    int sum = 0;
    char str[80]={'\0'};
    int i = 0, pos = 0;
    v = (char**) calloc((NSTRINGS * sizeof(char*)),1);

    while(1)
    {
        for(i = 0; i < NSTRINGS; i++)
        {
            printf("[%d] ", i+1);
            if(v[i] == NULL)
                printf("(Empty)\n");
            else
                printf("%s\n", v[i]);
        }

        do        
        {
            printf("New string's position (1 to %d): ", NSTRINGS);
            scanf("%d", &pos);
            getchar(); /* discards '\n' */
        }
        while(pos < 0 || pos > NSTRINGS);

        if (pos == 0){
            i = 0;
            break;
        }
        else{
            printf("New string: ");
            fgets(str, 80, stdin);
            str[strlen(str) - 1] = '\0';
            v[pos - 1] = realloc(v[pos - 1], strlen(str)+1);
            strcpy(v[pos - 1], str);
        }
    }
    free(v);
    v = NULL;
    return 0;
}

The sole objective is to allocate 3 strings in accordance to the space necessary (as to preserve the unused one). But then, even after using free(v), this is what valgrind returns to me (filling them in order by 1 2 3 and then 0):

[...]
==6760== 
==6760== HEAP SUMMARY:
==6760==     in use at exit: 20 bytes in 3 blocks
==6760==   total heap usage: 6 allocs, 3 frees, 2,092 bytes allocated
==6760== 
==6760== 20 bytes in 3 blocks are definitely lost in loss record 1 of 1
==6760==    at 0x4C2FA3F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6760==    by 0x4C31D84: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6760==    by 0x4009EB: main (in /home/esdeath/Prog/PL2/a.out)
==6760== 
==6760== LEAK SUMMARY:
==6760==    definitely lost: 20 bytes in 3 blocks
==6760==    indirectly lost: 0 bytes in 0 blocks
==6760==      possibly lost: 0 bytes in 0 blocks
==6760==    still reachable: 0 bytes in 0 blocks
==6760==         suppressed: 0 bytes in 0 blocks
==6760== 
==6760== For counts of detected and suppressed errors, rerun with: -v
==6760== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0

And with this, I have two questions I have really been trying to answer, but I am afraid my experience, for now, doesn't really let me:

  • First, it states I have 3 allocs even if I never use/reach the realloc function. Does this mean the calloc function is using 3 allocs all alone? And if so, why?

  • Secondly, how can I exactly free the 20 bytes (in this scenario)? I am really confused ...

Thanks in advance.


Side note: I recognize "realloc" may return NULL (in case it fails) and I added that into the program. Unless it was wrongly placed, Valgrind continued to report the same issue, so I ended up removing it (in the undo process) ...


Solution

  • You are not freeing the memory allocated by realloc. Add

    for (int i = 0; i < NSTRINGS; ++i)
        free(v[i]);
    

    before

    free(v);