C++'s std::string pools, debug builds? std::string and valgrind problems
I have a problem with many valgrind warnings about possible memory leaks in std::string, like this one:
120 bytes 开发者_如何学编程in 4 blocks are possibly lost in loss record 4,192 of 4,687
at 0x4A06819: operator new(unsigned long) (vg_replace_malloc.c:230)
by 0x383B89B8B0: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.8)
by 0x383B89C3B4: (within /usr/lib64/libstdc++.so.6.0.8)
by 0x383B89C4A9: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.8)
I'm wondering:
- does std::string (GCC 4.1.2) use any memory pools?
- if so, is there any way to disable the pools (in form of a debug build etc.)?
Check the FAQ. There is a section about “Memory leaks” in containers. You should
- check your version of Valgrind
- use a debug build of your program (and un-optimized)
- and define
GLIBCXX_FORCE_NEW
if necessary. (This is an environment variable that affects your program's runtime behavior, not a compile-time#define
as you might expect.)
This seems like a false positive. This can be suppressed as described in the manual
If I remember correctly, many STL allocators implement some kind of retention of memory. IE they do not release the memory allocated right away, but keep it around and reuse it. I certainly had many false positives in valgrind coming from memory allocated by my STL implementation.
The best way I have found to deal with the problem is (simply) to use the suppression file.
120 bytes are not enough for the pool. Do you exit() from your program?
I just had this problem and for me, it was because I was linking with a development version of a library, but my test code was picking up the older system-installed version. The changes were subtle enough that it would link and run without any apparent problems, but Valgrind would detect weird leaks. Using ldd
in place of valgrind
confirmed that it was picking up the wrong library file. Setting LD_LIBRARY_PATH
correctly fixed it, although the correct solution is to increment the library version as it's obviously not backwards compatible any more if you get this happening.
I have also seen this problem when an object hasn't been destroyed properly, such as a class with virtual
functions missing a virtual
destructor. When the class is put into a pointer-to-base-class and then destroyed, only the base class destructor runs, leaking anything allocated in the derived classes, like std::string
instances in your example. The hint here was to check which class was using the leaked string
, and follow the class hierarchy back to the base class and confirm it has an explicit virtual
destructor, even an empty one. I was assuming they were implicit if there are virtual
functions in a class but apparently not, and GCC doesn't warn you about this.
I had this issue because my program terminated due to an uncaught exception. Apparently the handler for uncaught exceptions does not clean everything up.
精彩评论