Certainly lost memory leak in program C

Can anyone shed some light on why Valgrind classifies this program as a memory leak "Definitely lost: 2 bytes in 1 block"? I understand that the commented line solves the problem, but I do not understand its classification. According to Valgrind docs, it seems that a memory leak should be classified as "indirectly achievable." I am also curious why this is even considered a memory leak and it would be useful to explain. Is it good practice to manually release everything, even if the program ends at the end of the main function?

 #include <stdlib.h> struct wrapper { char *data; }; char *strdup(const char *); struct wrapper *walloc(struct wrapper *root) { if (root == NULL){ root = (struct wrapper *) malloc(sizeof(struct wrapper)); root->data = strdup("H"); } return root; } int main(){ struct wrapper *root; root = NULL; root = walloc(root); //free(root->data); return 0; } 

Here is the output of Valgrind:

 $ valgrind --leak-check=full ./leak ==26489== Memcheck, a memory error detector ==26489== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==26489== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info ==26489== Command: ./leak ==26489== ==26489== ==26489== HEAP SUMMARY: ==26489== in use at exit: 2 bytes in 1 blocks ==26489== total heap usage: 2 allocs, 1 frees, 1,790 bytes allocated ==26489== ==26489== 2 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==26489== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==26489== by 0x4EB79C9: strdup (in /usr/lib/libc-2.20.so) ==26489== by 0x400542: walloc (leak.c:13) ==26489== by 0x400542: main (leak.c:23) ==26489== ==26489== LEAK SUMMARY: ==26489== definitely lost: 2 bytes in 1 blocks ==26489== indirectly lost: 0 bytes in 0 blocks ==26489== possibly lost: 0 bytes in 0 blocks ==26489== still reachable: 0 bytes in 0 blocks ==26489== suppressed: 0 bytes in 0 blocks ==26489== ==26489== For counts of detected and suppressed errors, rerun with: -v ==26489== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) 
+6
source share
2 answers

Thanks to @sharth for pointing me in the right direction. The direct loss was actually detected by Valgrind, but got confused due to the -O3 compilation, which completely removed root . Compilation without -O3 shows the correct direct loss of 8 bytes and the indirect loss of 2 bytes.

Also, thanks to @SylvainL and @Lundin for comments on their best practices.

FYI: Valgrind's corrected output is as follows:

 ==30492== Memcheck, a memory error detector ==30492== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==30492== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info ==30492== Command: ./leak ==30492== ==30492== ==30492== HEAP SUMMARY: ==30492== in use at exit: 10 bytes in 2 blocks ==30492== total heap usage: 3 allocs, 1 frees, 1,830 bytes allocated ==30492== ==30492== 10 (8 direct, 2 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2 ==30492== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==30492== by 0x400687: walloc (leak.c:12) ==30492== by 0x4006C6: main (leak.c:23) ==30492== ==30492== LEAK SUMMARY: ==30492== definitely lost: 8 bytes in 1 blocks ==30492== indirectly lost: 2 bytes in 1 blocks ==30492== possibly lost: 0 bytes in 0 blocks ==30492== still reachable: 0 bytes in 0 blocks ==30492== suppressed: 0 bytes in 0 blocks ==30492== ==30492== For counts of detected and suppressed errors, rerun with: -v ==30492== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) 
+2
source

strdup allocates memory on the heap (using malloc), and so you need to free this memory when it's no longer in use, as for any of your own direct call to malloc.

You must do this even when the program ends, because this is the only way to detect a memory leak. Of course, the concept of checking for a memory leak may seem a bit crowded when the program ends, because all the allocated memory is automatically freed by the OS, but do not forget that your small program is an exception. Typically, most programs take up a very large amount of memory at startup and can exit memory or run much slower if there are several memory leaks inside them.

Even a small program should be well written; otherwise, it will become impossible for you to write any large programs later, because your bad habits will translate into tons of coding errors.

+3
source

Source: https://habr.com/ru/post/975696/


All Articles