Reputation: 103
I have a program like this:
int *number0 = new int;
int main()
{
int *number1 = new int;
}
I thought, both memory allocations would introduce memory leaks, though valgrind only complains about number1 inside the main function. Why is that?
Upvotes: 4
Views: 1360
Reputation: 2984
Running this
int *x = new int;
int main()
{
return 0;
}
code (i.e without the leak in the main, compiled with g++ 4.8.1) using valgrind (3.8.1) with (-v --track-origins=yes --leak-check=full --show-reachable=yes
) I get:
==34301==
==34301== HEAP SUMMARY:
==34301== in use at exit: 4 bytes in 1 blocks
==34301== total heap usage: 1 allocs, 0 frees, 4 bytes allocated
==34301==
==34301== Searching for pointers to 1 not-freed blocks
==34301== Checked 189,064 bytes
==34301==
==34301== 4 bytes in 1 blocks are still reachable in loss record 1 of 1
==34301== at 0x4C2A879: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==34301==
==34301== LEAK SUMMARY:
==34301== definitely lost: 0 bytes in 0 blocks
==34301== indirectly lost: 0 bytes in 0 blocks
==34301== possibly lost: 0 bytes in 0 blocks
==34301== still reachable: 4 bytes in 1 blocks
==34301== suppressed: 0 bytes in 0 blocks
Which means that you should also pay attention to the in use at exit
category.
It doesn't seem like valgrind missed it, just placed it in another category, possibly because they assume something as lost only when you cannot by any means track down that address and release it, but this variable is never lost.
This however :
int *x = new int;
int main()
{
x = new int;
return 0;
}
Is detected as a leak as you really lose track of the memory you've allocated.
EDIT: As described in the Mem-check manual:
"Still reachable". This covers cases 1 and 2 (for the BBB blocks) above. A start-pointer or chain of start-pointers to the block is found. Since the block is still pointed at, the programmer could, at least in principle, have freed it before program exit. "Still reachable" blocks are very common and arguably not a problem. So, by default, Memcheck won't report such blocks individually.
So as noted before they do detect it, they just think it's less exciting
Upvotes: 4
Reputation: 16315
I see two leaks using valgrind 3.8.1 / g++ 4.8.1:
$ g++ -o foo -g foo.cc
$ valgrind ./foo
...
==7789== HEAP SUMMARY:
==7789== in use at exit: 8 bytes in 2 blocks
==7789== total heap usage: 2 allocs, 0 frees, 8 bytes allocated
==7789==
==7789== LEAK SUMMARY:
==7789== definitely lost: 4 bytes in 1 blocks
==7789== indirectly lost: 0 bytes in 0 blocks
==7789== possibly lost: 0 bytes in 0 blocks
==7789== still reachable: 4 bytes in 1 blocks
==7789== suppressed: 0 bytes in 0 blocks
The "definitely lost" bytes are in main
in my test.
Upvotes: 0
Reputation: 21637
This
int *number0 = new int;
is not a memory leak because it gets reclaimed at the end of execution.
This configuration is a [potential] memory leak because
int main()
{
int *number1 = new int;
}
some other part of the code could call
main () ;
and it could be called repeatedly.
Upvotes: -1
Reputation: 40633
Valgrind is not a perfect tool for detecting the presence or absence of all possible memory leaks, but rather a helpful tool that can detect some memory leaks. This means that valgrind output cannot be used to determine whether a particular piece of code contains or does not contain any leaks.
Neither of your new
s have corresponding delete
s, and in that sense, they are both leaked.
It is likely that valgrind considers the number0
memory to not be leaked because the memory it points to is reachable at the end of the program execution. In contrast to this, number1
goes out of scope, and so the memory it points to is not reachable at the end of the execution of your program, and so valgrind considers it to be leaked.
Upvotes: 4