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

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

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

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

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

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

Ответы [ 6 ]

5 голосов
/ 29 марта 2012

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

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

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

4 голосов
/ 29 марта 2012

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

В вашем конкретном примере утечка не имеет никакого значения, так как main немедленно выходит (эффективно) и память освобождается обратно вОПЕРАЦИОННЫЕ СИСТЕМЫ.Однако при написании производственного кода вам определенно не следует оставлять никаких утечек (даже таких, как тривиальные, как указано выше), поскольку код может быть перемещен в другую функцию, и утечка может фактически распространяться в течение всего времени жизни программ.

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

1 голос
/ 29 марта 2012

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

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

1 голос
/ 29 марта 2012

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

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

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

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

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

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

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

1 голос
/ 29 марта 2012

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

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

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

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

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

0 голосов
/ 29 марта 2012

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

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

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...