Разве вызов delete для динамически размещенного объекта не всегда является утечкой памяти?

c++ memory-management memory-leaks

541 просмотра

6 ответа

Из обсуждения, начатого здесь , я хотел бы знать, имеет ли утечка памяти следующий код:

int main()
{
   new int();
   //or
   int* x = new int();
   return 0;
}

Я знаю, что память восстанавливается ОС, но это все равно утечка? Я верю, что это так.

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

РЕДАКТИРОВАТЬ: Я не хочу начинать дебаты - «Я думаю, что ...» это не тот ответ, который я ищу. Меня больше всего интересуют источники - что такое книги на C ++ или веб-сайты, или что-то еще об этом.

Автор: Luchian Grigore Источник Размещён: 12.11.2019 09:59

Ответы (6)


1 плюс

Решение

Второй случай не утечка памяти.
Это не утечка, потому что у вас все еще есть указатель на выделенную память.
Чтобы определить утечку памяти, я хотел бы придерживаться определения, которое использует большинство инструментов анализа памяти, таких как valgrind:

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

Автор: Alok Save Размещён: 29.03.2012 08:35

5 плюса

Это зависит от того, как вы определяете «утечка». Согласно наиболее очевидному и единственно полезному определению, это не утечка, по крайней мере, на уровне приложений. Ведро не протекает, потому что вы намеренно позволяете конечному количеству воды вытекать. И практически говоря, приложение не терпит неудачу, потому что вы намеренно позволяете ограниченному набору объектов сохраняться после завершения программы.

Что касается утечек памяти, наше восприятие слова было окрашено "программами проверки утечек" - такими программами, как Purify или Valgrind. Их роль состоит в том, чтобы находить утечки (среди прочего), но у них нет никакого способа узнать, что является умышленным, а что нет, а что связано, а что нет. Таким образом, они придумали другие определения: объект, который недоступен, «просочился» (и в реальном коде есть большая вероятность, что это правда), или объект, который не был удален после того, как все деструкторы статических объектов были выполнены, имеет «утечка». В этом последнем случае определение, очевидно, неверно, и является бесполезным. Но есть достаточно случаев, когда такие вещи являются утечками, что разумно хотя бы о них предупреждать («возможные утечки»), при условии, что есть способ отфильтровать конкретные случаи. (Как Purify, так и Valgrind признают, что не все из этих случаев действительно являются утечками, и предоставляют различные механизмы фильтрации для их обнаружения.) Все это хорошо и хорошо - я очень рад, что у нас есть такие инструменты, но мы не должны позволяют им извращать язык.

И последнее напоминание: стандарт говорит, что стандартные объекты iostream ( std::coutи т. Д.) Никогда не будут уничтожены. Поэтому любые буферы, которые они выделяют, (вероятно) никогда не будут освобождены. Конечно, никто в здравом уме не будет рассматривать эти «утечки».

Автор: James Kanze Размещён: 29.03.2012 08:40

4 плюса

Приведенный выше код действительно имеет утечку. Что еще более важно, однако, если вместо того int, чтобы выделить, вы выделили специальный объект, скажем, объект подключения к серверу, если вы никогда не выполняете надлежащую очистку и вызов delete, деструктор объекта никогда не запускается, что может быть важно, если ваше подключение к серверу должно выполняться специальный код очистки (запись в файлы и т. д.).

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

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

Автор: Chris Размещён: 29.03.2012 08:28

1 плюс

Я бы определил утечку памяти таким образом

а) это занимает память

б) это больше не полезно для приложения

в) он более недоступен и, следовательно, больше не может быть удален

В соответствии с этим я бы оценил ваш образец как утечку памяти. Ваш образец показывает некритическую утечку. Критическая утечка - это постоянный захват памяти, что может произойти, пока не произойдет сбой приложения

Автор: stefan bachert Размещён: 29.03.2012 08:25

1 плюс

Это субъективное / спорно.

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

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

Утечка на уровне ОС не перестанет существовать после завершения работы приложения. Обычно в эту категорию (файлы) попадают некоторые другие ресурсы, но не память. Однако я не могу гарантировать, что не существует операционной системы / платформы, которая не очищает утечку памяти. По закону Мерфи такая платформа, вероятно, используется даже сегодня.

Поэтому, когда я говорю / пишу «утечка памяти», я имею в виду утечку на уровне приложения - любое выделение памяти, которое явно не удаляется APP. Каждое распределение, даже намеренное, попадает в категорию. Кроме того, обычно профилировщики выделения памяти и подобные инструменты будут жаловаться на ваши «преднамеренные утечки»,

Так что, да, в вашем коде есть утечка.

На мой взгляд, делать утечки даже нарочно, даже когда вы уверены, что ОС освободит их, - плохая идея, потому что это поощряет небрежное кодирование, и однажды вы не сможете удалить класс, который выпускает что-то важное в своем деструкторе, которое может ' быть очищенным ОС автоматически. Учитывая количество мусора, оставшегося в реестре Windows и папке временных файлов на среднем ПК, многие программисты обычно используют эту технику для ресурсов, которые не очищаются операционной системой должным образом. Так что лучшей идеей было бы избежать утечек.

Автор: SigTerm Размещён: 29.03.2012 08:32

-1 плюса

Да, есть утечка в 4 байта, потому что память, выделенная newне, deleted, и в течение жизни приложения это утечка.

По этой ссылке:

http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html

Memory leak description: Memory is allocated but not released causing an application to consume memory reducing the available memory for other applications and eventually causing the system to page virtual memory to the hard drive slowing the application or crashing the application when than the computer memory resource limits are reached. The system may stop working as these limits are approached.

Автор: Sanish Размещён: 29.03.2012 08:30
Вопросы из категории :
32x32