Освобождение динамично выделенной памяти

В C++, когда Вы делаете новую переменную на "куче" как это:

int* a = new int;

можно сказать, что C++ для исправления памяти при помощи удаляет как это:

delete a;

Однако, когда Ваша программа закрывается, она автоматически освобождает память, которая была выделена с новым?

7
задан Zerg 18 July 2010 в 16:48
поделиться

6 ответов

Да, она восстанавливается автоматически, но если вы собираетесь написать огромную программу, которая широко использует кучу и не вызывает нигде delete , у вас быстро закончится нехватка памяти кучи, что приведет к сбою вашей программы.

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

6
ответ дан 6 December 2019 в 19:32
поделиться

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

3
ответ дан 6 December 2019 в 19:32
поделиться

Не позволяйте людям говорить вам «да». C ++ не имеет понятия ОС, поэтому, говоря «да, ОС очистит это», мы уже говорим не о C ++, а о C ++, работающем в некоторой среде, которая может быть не вашей.

То есть, если вы что-то динамически выделяете, но никогда не освобождаете, значит, произошла утечка. Он может закончить свою жизнь только после того, как вы вызовете для него delete / delete [] . В некоторых ОС (и почти во всех ОС для настольных ПК) память будет освобождена (поэтому ее могут использовать другие программы). Но память не то же самое, что и ресурс! ОС может освободить всю память, которую она хочет, если у вас есть какое-то соединение с сокетом, которое нужно закрыть, какой-то файл, в который нужно завершить запись, и т. Д., ОС может этого не сделать. Важно не допустить утечки ресурсов. Я слышал о некоторых встроенных платформах, которые даже не восстанавливают память, которую вы не освободили, что приводит к утечке до тех пор, пока платформа не будет перезагружена.

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

Поэтому не используйте new T [N] , используйте std :: vector v (N); . Последнее не допустит утечки ресурсов. Не используйте new T; , используйте smart_ptr p (new T); . Умный указатель будет отслеживать объект и удалять его, когда он больше не используется. Это называется Scope-bound Resource Management (SBRM, также известное как более тупое название Resource-Acquisition is Initialization, или RAII.)

Обратите внимание, что нет единого " smart_ptr ". Вы должны выбрать, какой из них лучше. Текущий стандарт включает std :: auto_ptr , но он довольно громоздкий. (Его нельзя использовать в стандартных контейнерах.) Лучше всего использовать часть интеллектуальных указателей Boost или TR1, если ваш компилятор поддерживает это. Затем вы получаете shared_ptr , возможно, самый полезный интеллектуальный указатель, но есть и многие другие.

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

2
ответ дан 6 December 2019 в 19:32
поделиться

Нет, освободить его - это ваша ответственность. Кроме того, a должен быть указателем, поэтому он должен быть:

int *a = new int;
delete a;

Этот отличный ответ Брайана Р. Бонди подробно описывает, почему рекомендуется освобождать память, выделенную а .

Важно явно указать удалить, потому что у вас может быть код в деструкторе, который вы хотите выполнять. Как, может быть, я пишу какие-то данные в файл журнала. Если вы позволите ОС бесплатно ваша память для вас, ваш код в вашем деструктор не будет выполнен.

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

Что касается вызова удаления в целом, да вы всегда хотите вызвать удаление, или иначе у вас будет утечка памяти в ваша программа, которая приведет к новым распределения не удается.

1
ответ дан 6 December 2019 в 19:32
поделиться

Нет, когда программа выходит ("закрывается"), динамически выделяемая память остается как есть

РЕДАКТИРОВАТЬ:

Читая другие ответы, я должен быть более точным. Деструкторы динамически выделяемых объектов не будут работать, но память все равно будет освобождена любой достойной ОС.

PS: первая строка должна читать

int* a = new int;
1
ответ дан 6 December 2019 в 19:32
поделиться

Когда ваш процесс завершается, ОС восстанавливает контроль над всеми ресурсами, которые он использовал, включая память. Однако это, конечно, не приведет к обязательному запуску деструкторов C ++, поэтому это не панацея от явного не освобождения указанных ресурсов (хотя это не будет проблемой для int или других типов с noop dtors, конечно ;-).

0
ответ дан 6 December 2019 в 19:32
поделиться
Другие вопросы по тегам:

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