Considering this simple program,
// preprocessor directives
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
// define a struct
typedef struct structure
{
string str;
}
structure;
// create a pointer
structure *ptr;
int main(void)
{
// allocate memory for a structure
ptr = malloc(sizeof(structure));
if (ptr != NULL)
{
// prompt for a string
printf("Give me a string: ");
ptr -> str = GetString();
free(ptr); // doesn't free the string
}
return 0;
}
When compiling and running it under valgrind, inputting "hi", it gives the following output:
==3573== HEAP SUMMARY:
==3573== in use at exit: 3 bytes in 1 blocks
==3573== total heap usage: 3 allocs, 2 frees, 43 bytes allocated
==3573==
==3573== 3 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3573== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3573== by 0x4E37D1A: GetString (in /usr/lib/libcs50.so)
==3573== by 0x4007AD: main (structure.c:25)
==3573==
==3573== LEAK SUMMARY:
==3573== definitely lost: 3 bytes in 1 blocks
==3573== indirectly lost: 0 bytes in 0 blocks
==3573== possibly lost: 0 bytes in 0 blocks
==3573== still reachable: 0 bytes in 0 blocks
==3573== suppressed: 0 bytes in 0 blocks
==3573==
==3573== For counts of detected and suppressed errors, rerun with: -v
==3573== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Which clearly states that there's a memory leak cause by a call to GetString()
.
The problem is that I already freed ptr
which in turn contains a pointer to the same block of memory that contains the string created and returned by GetString()
. However, I'm still having a memory leak unless I free ptr -> str
manually. So what's going on here?