утечка памяти! как исправить? - PullRequest
4 голосов
/ 20 апреля 2011

Хорошо, так что я просто изучаю утечки памяти.Я запустил Valgrind, чтобы найти утечки памяти.я получаю следующее:

==6134== 24 bytes in 3 blocks are definitely lost in loss record 4 of 4
==6134==    at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==6134==    by 0x8048B74: readInput(char&) (in calc)

, значит ли это, что утечка есть в моей функции readInput?если так, как я могу избавиться от утечек памяти?вот оскорбительная функция:

double* readInput(char& command){
    std::string in;
    std::getline(std::cin, in);

    if(!isNumber(in)){
        if(in.length()>1){
            command = 0;
        }
        else{
            command = in.c_str()[0];
        }
        return NULL;
    }
    else{
        return new double(atof(in.c_str()));
    }
}

спасибо!

Ответы [ 3 ]

11 голосов
/ 20 апреля 2011
// ...
   return new double(atof(in.c_str()));
// ...

new получает ресурс из бесплатного магазина, который возвращается.Возвращаемое значение должно быть освобождено с помощью delete, чтобы избежать утечки памяти.


Если вы вызываете функцию в цикле while, number обязательно должно быть освобождено с использованием delete перед выполнениемцикл в следующий раз.Простое использование delete один раз приведет к освобождению только последнего полученного источника.

Редактировать:

// ....

while( condition1 )
{
     double *number = NULL ;
     number = readInput(command) ;

     if( condition2 )
     { .... }
     else
     { .... }

     delete number ;  // Should be done inside the loop itself.
                      // readInput either returns NULL or a valid memory location.
                      // delete can be called on a NULL pointer.
}
3 голосов
/ 20 апреля 2011

Вы возвращаете new дубль ... Когда это освободится?Вы делаете вызов delete на нем в какой-то момент ... верно?

Лично я бы рекомендовал просто возвращать ненулевое значение в случае успеха и нулевое значение в случае неудачи и поместить значение вdouble * (или double &) параметр.Таким образом, вам вообще не нужно беспокоиться о new.

2 голосов
/ 20 апреля 2011

Вы возвращаете только что выделенный double. Вы удаляете это где-нибудь?

Почему вы возвращаете указатель на недавно выделенный double? Почему бы просто не вернуть double? Возвращать восьмибайтовое временное значение не составляет особого труда, и вызывающий объект может решить, что он хочет с ним делать (включая выделение нового double в куче, если ему это нравится). Предполагая, что значения не велики, я бы предпочел вернуть временный. Концептуальное приближение new к реальному использованию облегчает управление памятью.

Кроме того, выделение большого количества очень маленьких блоков может привести к неэффективному использованию кучи и фрагментации кучи, так что программе может не хватить памяти, когда это не так, и она не сможет выделить большой кусок, даже если похоже, там еще много осталось. Это может иметь или не иметь значения (а дополнительное время, необходимое для выделения памяти, может иметь или не иметь значения, особенно в функции, время выполнения которой, вероятно, преобладает при вводе / выводе). Вероятно, это микрооптимизация, но если нет достаточных причин для таких небольших выделений, вы можете также привыкнуть не использовать их.

...