Consider the following C++ program:
#include <cstdlib> // for exit(3)
#include <string>
#include <iostream>
using namespace std;
void die()
{
exit(0);
}
int main()
{
string s("Hello, World!");
cout << s << endl;
die();
}
Running this through valgrind shows this (some output trimmed for brevity):
==1643== HEAP SUMMARY:
==1643== in use at exit: 26 bytes in 1 blocks
==1643== total heap usage: 1 allocs, 0 frees, 26 bytes allocated
==1643==
==1643== LEAK SUMMARY:
==1643== definitely lost: 0 bytes in 0 blocks
==1643== indirectly lost: 0 bytes in 0 blocks
==1643== possibly lost: 26 bytes in 1 blocks
==1643== still reachable: 0 bytes in 0 blocks
==1643== suppressed: 0 bytes in 0 blocks
As you can see, there’s a possibility that 26 bytes allocated on the heap were lost. I know that the std::string class has a 12-byte struct (at least on my 32-bit x86 arch and GNU compiler 4.2.4), and “Hello, World!” with a null terminator has 14 bytes. If I understand it correctly, the 12-byte structure contains a pointer to the character string, the allocated size, and the reference count (someone correct me if I’m wrong here).
Now my questions: How are C++ strings stored with regard to the stack/heap? Does a stack object exist for a std::string (or other STL containers) when declared?
P.S. I’ve read somewhere that valgrind may report a false positive of a memory leak in some C++ programs that use STL containers (and “almost-containers” such as std::string). I’m not too worried about this leak, but it does pique my curiosity regarding STL containers and memory management.
Others are correct, you are leaking because you are calling exit. To be clear, the leak isn’t the string allocated on the stack, it is memory allocated on the heap by the string. For example:
will not cause valgrind to report a leak.
The leak is probable (instead of definite) because you have an interior pointer to memory allocated on the heap. basic_string is responsible for this. From the header on my machine:
They key is that _M_p doesn’t point to the start of the memory allocated on the heap, it points to the first character in the string. Here is a simple example:
This will report a probable leak in valgrind. If you comment out the lines where I move m_data valgrind will report ‘still reachable’. If you uncomment the line where I set m_data to 0 you’ll get a definite leak.
The valgrind documentation has more information on probable leaks and interior pointers.