C ++ valgrind возможные утечки в строке STL - PullRequest
2 голосов
/ 10 сентября 2010

Я не вижу причину утечки ниже.

#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 говорит:

==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 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.

Проблема в функции fail ().Когда он выходит (), память просочилась.

Если я закомментирую выход (1);тогда нет никакой возможной утечки.

Кроме того, если я изменю сигнатуру с int fail (const std :: string str) на int fail (const char * str)

, то также не будет никакой возможной утечки.Мне не нравится это решение, так как я использую вещи типа fail (string + (LINE)), но независимо от того, что здесь происходит?

Я буду счастлив, если кто-нибудь сможет объяснить.

Спасибо!

(Упс. Тот же вопрос, который задавали до того, как я угадаю, извините! Valgrind сообщает об утечке памяти при присвоении значения строке )

Ответы [ 2 ]

21 голосов
/ 10 сентября 2010

Когда вы вызываете exit(), деструкторы автоматических объектов (локальные переменные) не вызываются.

В вашем конкретном примере деструктор std::string не вызывается, поэтому память, принадлежащаяstd::string никогда не освобождается.

Причиной отсутствия утечки, если у вас есть fail() принять const char*, является то, что для const char* нет деструктора;ничто не освобождается при уничтожении указателя.Если указатель указывает на динамически выделенную память, то эта память должна быть освобождена (вами) до выхода из программы, в противном случае у вас будет утечка памяти.Если он указывает на строковый литерал, то утечки памяти нет, поскольку строковые литералы имеют статическую длительность хранения (то есть они существуют в течение всего времени жизни вашей программы).

8 голосов
/ 10 сентября 2010

Джеймс МакНеллис уже написал правильный ответ.Но я хотел бы добавить несколько вещей:

  1. Всегда полезно писать программное обеспечение так, чтобы ему не приходилось вызывать exit () - это поможет вам улучшитьОбщее проектирование, определение и понимание времени жизни объекта (за исключением очень особых - довольно низких - случаев).

  2. Как вы видите здесь, это важно при использовании таких инструментов, как valgrind!«Чистая» процедура выключения позволяет вам чувствовать себя в безопасности, тогда все работает нормально, как вы и ожидали;) Процедура чистого выключения в исключительных случаях должна быть требованием для каждого программного обеспечения.рассмотрим throw исключение вместо вызова некоторой fail() функции.Когда генерируется исключение, стек будет разматываться, поэтому в вашем случае будет вызван деструктор std::string.

...