Другие верны, вы просачиваетесь, потому что вы звоните из выхода. Для ясности, утечка - это не строка, выделенная в стеке, а память, выделенная в куче строкой. Например:
struct Foo { };
int main()
{
Foo f;
die();
}
не приведет к тому, что valgrind сообщит об утечке.
Утечка вероятна (вместо определенной), потому что у вас есть внутренний указатель на память, выделенную в куче. basic_string несет ответственность за это. Из шапки на моей машине:
* A string looks like this:
*
* @code
* [_Rep]
* _M_length
* [basic_string<char_type>] _M_capacity
* _M_dataplus _M_refcount
* _M_p ----------------> unnamed array of char_type
* @endcode
*
* Where the _M_p points to the first character in the string, and
* you cast it to a pointer-to-_Rep and subtract 1 to get a
* pointer to the header.
Они указывают на то, что _M_p не указывает на начало памяти, выделенной в куче, а указывает на первый символ в строке. Вот простой пример:
struct Foo
{
Foo()
{
// Allocate 4 ints.
m_data = new int[4];
// Move the pointer.
++m_data;
// Null the pointer
//m_data = 0;
}
~Foo()
{
// Put the pointer back, then delete it.
--m_data;
delete [] m_data;
}
int* m_data;
};
int main()
{
Foo f;
die();
}
Это сообщит о вероятной утечке в валгринде. Если вы закомментируете строки, в которых я перемещаюсь, m_data valgrind сообщит «все еще достижимо». Если вы раскомментируете строку, где я установил m_data в 0, вы получите определенную утечку.
Документация Valgrind содержит больше информации о возможных утечках и внутренних указателях.