<qandadiv id="faq.unexpected" xreflabel="Valgrind behaves unexpectedly">
<title>Valgrind behaves unexpectedly</title>
-<qandaentry id="faq.reports">
- <question id="q-reports">
- <para>My program uses the C++ STL and string classes. Valgrind
- reports 'still reachable' memory leaks involving these classes at
- the exit of the program, but there should be none.</para>
- </question>
- <answer id="a-reports">
- <para>First of all: relax, it's probably not a bug, but a feature.
- Many implementations of the C++ standard libraries use their own
- memory pool allocators. Memory for quite a number of destructed
- objects is not immediately freed and given back to the OS, but kept
- in the pool(s) for later re-use. The fact that the pools are not
- freed at the exit of the program cause Valgrind to report this
- memory as still reachable. The behaviour not to free pools at the
- exit could be called a bug of the library though.</para>
-
- <para>Using GCC, you can force the STL to use malloc and to free
- memory as soon as possible by globally disabling memory caching.
- Beware! Doing so will probably slow down your program, sometimes
- drastically.</para>
- <itemizedlist>
- <listitem>
- <para>With GCC 2.91, 2.95, 3.0 and 3.1, compile all source using
- the STL with <literal>-D__USE_MALLOC</literal>. Beware! This was
- removed from GCC starting with version 3.3.</para>
- </listitem>
- <listitem>
- <para>With GCC 3.2.2 and later, you should export the
- environment variable <literal>GLIBCPP_FORCE_NEW</literal> before
- running your program.</para>
- </listitem>
- <listitem>
- <para>With GCC 3.4 and later, that variable has changed name to
- <literal>GLIBCXX_FORCE_NEW</literal>.</para>
- </listitem>
- </itemizedlist>
-
- <para>There are other ways to disable memory pooling: using the
- <literal>malloc_alloc</literal> template with your objects (not
- portable, but should work for GCC) or even writing your own memory
- allocators. But all this goes beyond the scope of this FAQ. Start
- by reading
- <ulink
- url="http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#4_4_leak">
- http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#4_4_leak</ulink>
- if you absolutely want to do that. But beware:
- allocators belong to the more messy parts of the STL and
- people went to great lengths to make the STL portable across
- platforms. Chances are good that your solution will work on your
- platform, but not on others.</para>
- </answer>
-</qandaentry>
-
-
<qandaentry id="faq.unhelpful">
<question id="q-unhelpful">
<para>The stack traces given by Memcheck (or another tool) aren't
</answer>
</qandaentry>
+<qandaentry id="faq.reports">
+ <question id="q-reports">
+ <para>My program uses the GNU C++ standard library container and string classes.
+ Valgrind reports 'still reachable' memory leaks involving these classes at the exit
+ of the program, but there should be none.</para>
+ </question>
+ <answer id="a-reports">
+ <para>If Valgrind reports a leak in C++ code using a GCC version dating from 2005 or later,
+ the most likely cause is a bug in your code, such as a missing deallocation or
+ a cyclic reference.</para>
+ <para>If you are using an old version of GCC (version 3.4 from 2004 or earlier)
+ or if you are using the optional <literal>__gnu_cxx::pool_alloc</literal> or
+ <literal>__gnu_cxx::__mt_alloc</literal> (both of which are considered obsolete), then this
+ may be a feature of the standard library implementation and not a bug in your
+ code.</para>
+ <para>These old C++ libraries and specialised allocators use their own
+ memory pools. Memory for quite a number of destructed objects is not immediately
+ freed and given back to the OS, but kept in the pool(s) for later re-use.
+ The fact that the pools are not freed at the exit of the program causes
+ Valgrind to report this memory as still reachable.</para>
+
+ <para>Using GCC, you can force the standard library to use new and delete
+ directly, thus globally disabling memory caching.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>With GCC 3.4 and later you should export the environment variable
+ <literal>GLIBCXX_FORCE_NEW</literal> before running your program.</para>
+ </listitem>
+ <listitem>
+ <para>With GCC 3.2.2 up to GCC 3.4, the name of the environment
+ variable was <literal>GLIBCPP_FORCE_NEW</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>With GCC 2.91, 2.95, 3.0 and 3.1, compile all source using
+ the standard library with <literal>-D__USE_MALLOC</literal>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If you replace the default <literal>std::allocator</literal> with your own allocator
+ or if you use a <literal>std::pmr::polymorphic_allocator</literal>, then you may have
+ similar issues. Dealing with these issues is beyond the scope of this document.</para>
+ <para>To read more about C++ allocators, see the cppreference pages on <ulink url="https://en.cppreference.com/cpp/memory/allocator">allocator</ulink>
+ or <ulink url="https://en.cppreference.com/cpp/memory/polymorphic_allocator">polymorphic_allocator</ulink>.</para>
+ <para>To read more about how to teach Valgrind to understand memory pools, see <xref linkend="mc-manual.mempools"/>
+ for details. This <ulink url="https://developers.redhat.com/articles/2022/03/23/use-valgrind-memcheck-custom-memory-manager#">guide</ulink>
+ also shows how to instrument memory pools.</para>
+ </answer>
+</qandaentry>
+
</qandadiv>