3

Consider this code:

#include <stdlib.h>

int* alloc()
{
    return malloc(250 * sizeof(int));
}

int main()
{
    int i;
    int *vars[3];
    for(i = 0; i < 3; ++i) {
        vars[i] = alloc();
    }
}

Valgrind output:

$ valgrind --leak-check=full ./lala
==16775== Memcheck, a memory error detector
==16775== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==16775== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==16775== Command: ./lala
==16775== 
==16775== 
==16775== HEAP SUMMARY:
==16775==     in use at exit: 3,000 bytes in 3 blocks
==16775==   total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==16775== 
==16775== 3,000 bytes in 3 blocks are definitely lost in loss record 1 of 1
==16775==    at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16775==    by 0x4005B3: alloc (lala.c:5)
==16775==    by 0x4005DF: main (lala.c:13)
==16775== 
==16775== LEAK SUMMARY:
==16775==    definitely lost: 3,000 bytes in 3 blocks
==16775==    indirectly lost: 0 bytes in 0 blocks
==16775==      possibly lost: 0 bytes in 0 blocks
==16775==    still reachable: 0 bytes in 0 blocks
==16775==         suppressed: 0 bytes in 0 blocks
==16775== 
==16775== For counts of detected and suppressed errors, rerun with: -v
==16775== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

According to Valgrind's manual:

If --leak-check is set appropriately, for each remaining block, Memcheck determines if the block is reachable from pointers within the root-set. The root-set consists of (a) general purpose registers of all threads, and (b) initialized, aligned, pointer-sized data words in accessible client memory, including stacks.

For what I understand, since the "definitely lost" memory are still pointed to from the main() function's stack, they should be categorized as "still reachable", right?

If not, how can I configure Valgrind to try to reach memory blocks from main's stack, to determine if they are "still reachable"?

EDIT:

Please don't tell me to free the pointers at the end of main, that is not what I am asking about. For the distinction between "still reachable" and "definitely lost" on Valgrind terms, see this answer: https://stackoverflow.com/a/3857638/578749

Community
  • 1
  • 1
lvella
  • 12,754
  • 11
  • 54
  • 106
  • When your main ends, you definitely lost any chance to free the allocated memory, so it makes sense. Free the three blocks at the end of the method, and the error should disappear. – skypjack Jun 25 '15 at 21:48
  • My answer was not the right answer. I deleted it. – Iharob Al Asimi Jun 25 '15 at 21:53
  • 1
    When the main ends, the program ends, and the memory will be freed anyway. See [this answer](http://stackoverflow.com/a/3857638/578749). – lvella Jun 25 '15 at 21:54

1 Answers1

16

Your memory is definitely lost when the stack of main is destroyed, that is, when it returns. Thus, the solution is not to return.

#include <stdlib.h>
int main()
{
    /* your code here */
    exit(0);
}

The behavior or main returning 0 or exit(0) should be equivalent.

Now the output is:

==5035== Memcheck, a memory error detector
==5035== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5035== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5035== Command: ./a.out
==5035== 
==5035== 
==5035== HEAP SUMMARY:
==5035==     in use at exit: 3,000 bytes in 3 blocks
==5035==   total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==5035== 
==5035== LEAK SUMMARY:
==5035==    definitely lost: 0 bytes in 0 blocks
==5035==    indirectly lost: 0 bytes in 0 blocks
==5035==      possibly lost: 0 bytes in 0 blocks
==5035==    still reachable: 3,000 bytes in 3 blocks
==5035==         suppressed: 0 bytes in 0 blocks
==5035== Reachable blocks (those to which a pointer was found) are not shown.
==5035== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5035== 
==5035== For counts of detected and suppressed errors, rerun with: -v
==5035== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
rodrigo
  • 94,151
  • 12
  • 143
  • 190