Home > Software design >  Calling free() on a variable initialised by strdup still results in memory leak
Calling free() on a variable initialised by strdup still results in memory leak

Time:11-29

I have the following code:

static const char * path[2];


int main(int argc, char *argv[]) {
    // validate argument

    char * temp = dirname(dirname(strdup(argv[optind])));
    path[0] = temp
    path[1] = NULL;

    // do stuff

    free(temp);
    return 0;
}

I understand that strdup allocates memory which needs to be freed in order to avoid memory leaks. I attempt to do this before returning from the function but the leak still presists.

Valgrind output:

$ valgrind --leak-check=full -s ./tstprog meta_schema.schema 
==36849== Memcheck, a memory error detector
==36849== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==36849== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==36849== Command: ./tstprog meta_schema.schema
==36849== 
==36849== Invalid free() / delete / delete[] / realloc()
==36849==    at 0x484827F: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==36849==    by 0x11577A: main (tstprog.c:134)
==36849==  Address 0x4a42ae1 is 0 bytes inside data symbol "dot.0"
==36849== 
==36849== 
==36849== HEAP SUMMARY:
==36849==     in use at exit: 19 bytes in 1 blocks
==36849==   total heap usage: 255 allocs, 255 frees, 64,111 bytes allocated
==36849== 
==36849== 19 bytes in 1 blocks are definitely lost in loss record 1 of 1
==36849==    at 0x4845899: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==36849==    by 0x49240CF: strdup (in /usr/lib/libc.so.6)
==36849==    by 0x1155C1: main (tstprog.c:108)
==36849== 
==36849== LEAK SUMMARY:
==36849==    definitely lost: 19 bytes in 1 blocks
==36849==    indirectly lost: 0 bytes in 0 blocks
==36849==      possibly lost: 0 bytes in 0 blocks
==36849==    still reachable: 0 bytes in 0 blocks
==36849==         suppressed: 0 bytes in 0 blocks
==36849== 
==36849== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==36849== 
==36849== 1 errors in context 1 of 2:
==36849== Invalid free() / delete / delete[] / realloc()
==36849==    at 0x484827F: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==36849==    by 0x11577A: main (tstprog.c:134)
==36849==  Address 0x4a42ae1 is 0 bytes inside data symbol "dot.0"
==36849== 
==36849== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

I have also looked at this post and they seem to do the same thing when they call free(who->name).

What am I missing?

CodePudding user response:

Quoting from dirname man page

   Both dirname() and basename() return pointers to null-terminated strings.  
   (Do not pass these pointers to free(3).)

You are not freeing strdup result (which you can, indeed). You are freeing dirname result. Which you can't.

  • Related