C++ valgrind possible leaks on STL string
I do not see the reason of the leak below.
#include <iostream>
#include <cstdlib>
int fail(const std::string str)
{
std::cerr<< str << std::endl;
exit(1);
}
const std::string usage()
{
std::string a = "a";
return a;
}
int main()
{
fail(usage());
return 0;
}
Valgrind says:
==7238== 14 bytes in 1 blocks are possibly lost in loss record 1 of 1
==7238== at 0x402377E: operator new(unsigned) (vg_replace_malloc.c:224)
==7238== by 开发者_JS百科0x40E7C03: std::string::_Rep::_S_create(unsigned, unsigned,
std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.10)
==7238== by 0x40E8864: (within /usr/lib/libstdc++.so.6.0.10)
==7238== by 0x40E89D5: std::string::string(char const*, std::allocator<char> const&)
(in /usr/lib/libstdc++.so.6.0.10)
==7238== by 0x80488EC: usage() (main.cpp:12)
==7238== by 0x804897C: main (main.cpp:18)
==7238== LEAK SUMMARY:
==7238== definitely lost: 0 bytes in 0 blocks.
==7238== possibly lost: 14 bytes in 1 blocks.
==7238== still reachable: 0 bytes in 0 blocks.
==7238== suppressed: 0 bytes in 0 blocks.
The problem is in the fail() function. As it exits(), the memory is leaked.
If I comment out exit(1); then there is no possible leak.
Also, if I change the signature from int fail(const std::string str) to int fail(const char* str)
then there is no possible leak as well. I don't like this solution, as I am using fail(string + (LINE)) type of things, but regardless, what is going on here?
I will be happy if someone can explain.
Thanks!
(upps. same question asked before I guess, sorry! Valgrind reports memory leak when assigning a value to a string)
When you call exit()
, the destructors of automatic objects (local variables) do not get called.
In your specific example, the std::string
destructor is not called, so the memory owned by the std::string
is never deallocated.
The reason there is no leak if you have fail()
take a const char*
is that there is no destructor for const char*
; nothing is deallocated when a pointer is destroyed. If the pointer points to dynamically allocated memory, then that memory must be deallocated (by you) before the program exits, otherwise you have a memory leak. If it points to a string literal, then there is no memory leak because string literals have static storage duration (that is, they exist for the entire lifetime of your program).
James McNellis already wrote a correct answer. But I'd like to add some things:
It is always a good thing to write software in a way that it does not have to call exit() - this helps you improve the overall design, specify and understand object lifetimes (except in very special - rather low level - cases..).
As you see here, this is important when using tools like valgrind! A "clean" shutdown procedure makes you feel safe, then everything worked fine, as you expected ;) A clean shutdown procedure in exceptional cases should be a requirement of every software.
You should consider to throw
an exception instead of calling some fail()
function. When an exception is thrown, the stack will be unwound, so the std::string
destructor in your case would be called.
精彩评论