Утечки памяти в C++ (через new+delete)

Иногда обновления имеют немного отличающиеся разметки фс и немного отличающиеся программы и мелкие различия от чистых установок. Но, всегда, смотря на спецификации Вашего ноутбука:

LG Z1 (XNote R200)

Спецификации Intel Core 2 Duo T7300 (2,0 ГГц), 1 ГБ RAM, жесткого диска на 160 ГБ, 12,1-дюймового экрана (1280 x 800 pixels), ATI Radeon HD 2400, Bluetooth, WLAN,

, Что 1 ГБ поршня там смотрит очень близко к минимуму для единицы. Попробуйте рабочую 2-ю единицу или возможно xfce/gnome3 для лучшего опыта. Но, я не знаю о причудливых проблемах файловой системы. Возможно, единица, отказывающая на Вашей машине, вызывает повреждение???

6
задан joemoe 30 August 2009 в 21:35
поделиться

10 ответов

Если вы имеете в виду, нужно ли вам такое же количество экземпляров delete в исходном коде, как и экземпляров new , то нет. У вас могут быть объекты new ed в нескольких местах, но все эти объекты удаляют d одной и той же строкой кода. На самом деле это обычная идиома.

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

Edit

Технически, каждый успешный вызов выделения памяти должен согласовываться с вызовом удаления, который принимает возвращенный указатель из исходного вызова выделения.

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

Есть новые выражения, которые создают объекты в предварительно выделенной памяти ( размещение новое ). Эти не должны соответствовать выражению удаления, но может потребоваться освободить предварительно выделенную память таким образом, чтобы это соответствовало исходному выделению.

Есть новые выражения, которые создают объекты в предварительно выделенной памяти (размещение new ). Эти не должны соответствовать выражению удаления, но может потребоваться освободить предварительно выделенную память таким образом, чтобы это соответствовало исходному выделению.

Есть новые выражения, которые создают объекты в предварительно выделенной памяти (размещение new ). Эти не должны соответствовать выражению удаления, но может потребоваться освободить предварительно выделенную память таким образом, чтобы это соответствовало исходному выделению.

19
ответ дан 8 December 2019 в 02:16
поделиться

Если вы имели в виду «в исходном коде», то №

См. Этот код:

int main()
{
    char* buffer = 0; 


    for( int i = 0; i < 42; ++i )
    {
        buffer = new char[1024];
    }

    delete [] buffer; 

    return 0;
}

1 новый, 1 удаленный, ((42 - 1) * 1024) байтов утечка памяти.

Если вы имели в виду «вызов нового и удаления во время выполнения», тогда да. Каждая память, полученная с помощью new, должна быть освобождена с помощью delete:

int main()
{
    std::vector<char*> bufferList; // or nullptr or NULL whatever


    for( int i = 0; i < 42; ++i )
    {
        bufferList.push_back( new char[1024] );
    }

    for( int i = 0; i < bufferList.size(); ++i )
    {
        delete [] bufferList[i]; 
    }

    return 0;
}

Теперь при выполнении мы получили удаление, выполняемое для каждого нового выполнения <=> без утечки.

17
ответ дан 8 December 2019 в 02:16
поделиться

Да. Каждое новое должно сопровождаться удалением.

Однако удаление часто скрыто от вас - например:

{
  std::auto_ptr p( new Foo );
}

Здесь есть новое, но удаление (которое происходит автоматически в конце блока) скрыт в реализация std :: auto_ptr.

7
ответ дан 8 December 2019 в 02:16
поделиться

Существуют сложные инструменты, такие как Rational Purify, для проверки утечек памяти в программах на C ++. К сожалению, проверка отсутствия утечек памяти в самом коде перед запуском - весьма нетривиальная проблема. Поэтому сохраняйте простоту, следуйте лучшим практикам и тестируйте как можно больше во время выполнения.

2
ответ дан 8 December 2019 в 02:16
поделиться

Не совсем так. Любой объект, выделенный с помощью оператора new, должен быть освобожден с помощью оператора удаления. Хорошо иметь несколько операторов (new или delete) в разных ветках.

Лично я использую boost shared_ptr при написании кода на C ++.

0
ответ дан 8 December 2019 в 02:16
поделиться

Если вы хотите найти предварительный способ обнаружения утечек памяти, подсчет новых / удалений не поможет. Однако, если вы используете MS VC, вы можете использовать CRT для выполнения очень простого, но полезного для вас обнаружения утечек:

_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT);
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

Это заставит CRT вызвать _CrtDumpMemoryLeaks прямо перед выгрузкой CRT. Если они есть, они будут сброшены на консоль:

Detected memory leaks!
Dumping objects ->
{342} normal block at 0x05A28FD8, 4 bytes long.
 Data: <    > 00 00 00 00 
Object dump complete.

Существует также методика определения точного места утечки по номеру блока ({342}), но иногда достаточно знать, есть ли там есть какие-либо утечки.

Это не отменяет необходимости в надлежащих средствах обнаружения утечек памяти, но может ограничить их потребность.

Я всегда использую эту технику в модульных тестах. Позволяет мне очень быстро обнаруживать очень глупые утечки памяти.

0
ответ дан 8 December 2019 в 02:16
поделиться

Вы спрашиваете о количестве вызовов во время выполнения (например, подсчитанном с помощью инструментального профилировщика)? Точно одинаковое количество обращений к операторам new (исключая размещение new) и delete не является ни необходимым, ни достаточным условием отсутствия утечек кода:

  • Удаление NULL безвреден, поэтому многие программы без утечек вызывают delete чаще, чем new .
  • Программа, которая вызывает delete столько раз, сколько new , но иногда удаляет NULL , имеет утечку. То же самое и с некоторыми программами, которые вызывают delete чаще, чем new , но иногда удаляют NULL .
  • Программа, которая чаще вызывает new чем delete имеет утечку.

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

Кроме того, программы, которые не пропускают выделенную ими память, могут по-прежнему пропускать другие ресурсы (например, дескрипторы файлов ОС).

То же самое и с некоторыми программами, которые вызывают delete чаще, чем new , но иногда удаляют NULL .
  • Программа, которая чаще вызывает new чем delete имеет утечку.
  • Чтобы убедиться в отсутствии утечек, вы должны убедиться, что каждый адрес, возвращаемый из new , передается в delete , а не просто убедитесь, что количество вызовов совпадает. И даже это упрощение, поскольку адреса повторно используются для множественного распределения.

    Кроме того, программы, которые не пропускают выделенную ими память, могут по-прежнему пропускать другие ресурсы (например, дескрипторы файлов ОС).

    То же самое и с некоторыми программами, которые вызывают delete чаще, чем new , но иногда удаляют NULL .
  • Программа, которая чаще вызывает new чем delete имеет утечку.
  • Чтобы убедиться в отсутствии утечек, вы должны убедиться, что каждый адрес, возвращаемый из new , передается в delete , а не просто убедитесь, что количество вызовов совпадает. И даже это упрощение, поскольку адреса повторно используются для множественного распределения.

    Кроме того, программы, которые не пропускают выделенную ими память, могут по-прежнему пропускать другие ресурсы (например, дескрипторы файлов ОС).

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

    Кроме того, программы, которые не пропускают выделенную ими память, могут по-прежнему пропускать другие ресурсы (например, дескрипторы файлов ОС).

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

    Кроме того, программы, которые не пропускают выделенную ими память, могут по-прежнему пропускать другие ресурсы (например, дескрипторы файлов ОС).

    1
    ответ дан 8 December 2019 в 02:16
    поделиться

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

    Вам необходимо сопоставить количество вызовов новый с количеством вызовов удалить .

    Чаще всего это усложняется, что это.

    -1
    ответ дан 8 December 2019 в 02:16
    поделиться

    Чтобы избежать утечек памяти, ваше приложение должно освободить всю память, которую оно больше не использует , если только оно не выделит ее во время завершения. Нет понятия утечки памяти в программе без цикла обработки событий (потому что, ну, их время жизни - завершение с самого начала :-))

    Но это для взрослых парней. Для вас да, каждое новое должно иметь соответствующее удаление (это означает, что во время выполнения программы, а не в вашем исходном коде!) Создавайте хороший код, не стреляйте себе в ногу!

    -4
    ответ дан 8 December 2019 в 02:16
    поделиться

    Вам необходимо сопоставить вызов для нового с вызовом для удаления. Поскольку C ++ является объектно-ориентированным языком программирования, рассмотрите возможность использования класса для создания (в конструкторе) и удаления (в деструкторе) переменных, объявленных или используемых в классе. Фактически, это будет использование преимущества идиомы Resource Acquisition Is Initialization или RAII (для краткости). Если вам не хочется программировать это самостоятельно, вы всегда можете использовать память из STL .

    Одно важное замечание: если вы выделяете переменную новым, и ваш код может вызвать исключение, вы можете вызвать утечку памяти, если это исключение не будет обнаружено и переменная будет удалена соответствующим образом.

    1
    ответ дан 8 December 2019 в 02:16
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: