The following is a leak:
static void memeat(void) { static char *foo = NULL; foo = malloc(1024); return; }
Valgrind output:
==16167== LEAK SUMMARY: ==16167== definitely lost: 4,096 bytes in 4 blocks ==16167== indirectly lost: 0 bytes in 0 blocks ==16167== possibly lost: 0 bytes in 0 blocks ==16167== still reachable: 1,024 bytes in 1 blocks ==16167== suppressed: 0 bytes in 0 blocks ==16167== Rerun with --leak-check=full to see details of leaked memory
Note. still reachable (1024 bytes) - the result of the last occurrence of memeat() . The static pointer still retained a valid reference to the last memeat() block allocated when exiting the program. Only not the previous blocks.
The following is a leak:
static void memeat(void) { static char *foo = NULL; foo = realloc(foo, 1024); return; }
Valgrind Output:
==16244== LEAK SUMMARY: ==16244== definitely lost: 0 bytes in 0 blocks ==16244== indirectly lost: 0 bytes in 0 blocks ==16244== possibly lost: 0 bytes in 0 blocks ==16244== still reachable: 1,024 bytes in 1 blocks ==16244== suppressed: 0 bytes in 0 blocks ==16244== Rerun with --leak-check=full to see details of leaked memory
Here, the specified address foo was freed, and foo now points to the newly allocated address and will continue to do so next time memeat() .
Explanation:
The static storage type says that the pointer foo will point to the same address that is initialized each time the function is entered. However, if you change this address every time a function is entered via malloc() or calloc() , you have lost the link to the blocks from the previous distribution. Consequently, a leak, as it is either going to return a new address.
'Still Reachable' in valgrind means that all allocated heap blocks still have a valid pointer to access / manipulate / free them when exiting. This is similar to allocating memory in main() and not freeing it, just relying on the OS to recover the memory.
In short, yes - you have a leak. However, you can fix this quite easily. Just keep in mind that you really rely on your OS to recover memory unless you add another argument to your function that simply tells ToHexString to call the static pointer for free, which you could use when exiting.
Similar to this: (full test program)
#include <stdlib.h> static void memeat(unsigned int dofree) { static char *foo = NULL; if (dofree == 1 && foo != NULL) { free(foo); return; } foo = realloc(foo, 1024); return; } int main(void) { unsigned int i; for (i = 0; i < 5; i ++) memeat(0); memeat(1); return 0; }
Valgrind Output:
==16285== HEAP SUMMARY: ==16285== in use at exit: 0 bytes in 0 blocks ==16285== total heap usage: 6 allocs, 6 frees, 6,144 bytes allocated ==16285== ==16285== All heap blocks were freed
Note on final output :
Yes, in fact, 6144 bytes were allocated according to the fact that malloc() was returned at program startup, but it just means that the static pointer was freed and then redistributed according to the number of times memeat() . The actual use of the program heap at any given time was actually only 2 * 1024, 1k to highlight the new pointer, while the old one still existed, waiting to be copied to the new one.
Again, it should not be too difficult to configure your code, but it is not clear to me why you are using static storage to get started.