В C++, когда Вы делаете новую переменную на "куче" как это:
int* a = new int;
можно сказать, что C++ для исправления памяти при помощи удаляет как это:
delete a;
Однако, когда Ваша программа закрывается, она автоматически освобождает память, которая была выделена с новым?
Да, она восстанавливается автоматически, но если вы собираетесь написать огромную программу, которая широко использует кучу и не вызывает нигде delete
, у вас быстро закончится нехватка памяти кучи, что приведет к сбою вашей программы.
Следовательно, необходимо тщательно управлять своей памятью и освобождать динамически выделяемые данные с помощью соответствующего delete
для каждого нового
(или delete []
, если используя new []
), как только вам больше не потребуется указанная переменная.
Когда процесс завершается, память возвращается обратно операционной системой. Конечно, этот аргумент ни в коем случае не должен использоваться для того, чтобы программа не выполняла надлежащее управление памятью.
Не позволяйте людям говорить вам «да». C ++ не имеет понятия ОС, поэтому, говоря «да, ОС очистит это», мы уже говорим не о C ++, а о C ++, работающем в некоторой среде, которая может быть не вашей.
То есть, если вы что-то динамически выделяете, но никогда не освобождаете, значит, произошла утечка. Он может закончить свою жизнь только после того, как вы вызовете для него delete
/ delete []
. В некоторых ОС (и почти во всех ОС для настольных ПК) память будет освобождена (поэтому ее могут использовать другие программы). Но память не то же самое, что и ресурс! ОС может освободить всю память, которую она хочет, если у вас есть какое-то соединение с сокетом, которое нужно закрыть, какой-то файл, в который нужно завершить запись, и т. Д., ОС может этого не сделать. Важно не допустить утечки ресурсов. Я слышал о некоторых встроенных платформах, которые даже не восстанавливают память, которую вы не освободили, что приводит к утечке до тех пор, пока платформа не будет перезагружена.
Вместо того, чтобы динамически выделять вещи в сыром виде (то есть вы тот, кто должен их явно удалить), оберните их в автоматически выделяемые (выделенные стеком) контейнеры; невыполнение этого считается плохой практикой и делает ваш код чрезвычайно беспорядочным.
Поэтому не используйте new T [N]
, используйте std :: vector
. Последнее не допустит утечки ресурсов. Не используйте 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
, возможно, самый полезный интеллектуальный указатель, но есть и многие другие.
Если каждый указатель на динамически выделяемую память находится в объекте, который будет разрушаться (т. Е. Не в другом динамически выделяемом объекте), и этот объект знает, что нужно освободить память, этот указатель гарантированно будет освобожден. Этот вопрос даже не должен быть проблемой, так как у вас никогда не должно быть утечки.
Нет, освободить его - это ваша ответственность. Кроме того, a
должен быть указателем, поэтому он должен быть:
int *a = new int;
delete a;
Этот отличный ответ Брайана Р. Бонди подробно описывает, почему рекомендуется освобождать память, выделенную а
.
Важно явно указать удалить, потому что у вас может быть код в деструкторе, который вы хотите выполнять. Как, может быть, я пишу какие-то данные в файл журнала. Если вы позволите ОС бесплатно ваша память для вас, ваш код в вашем деструктор не будет выполнен.
Большинство операционных систем будут освобождены память, когда ваша программа закончится. Но это хорошая практика - освободить его себя и как я уже сказал выше ОС не будет вызывать ваш деструктор.
Что касается вызова удаления в целом, да вы всегда хотите вызвать удаление, или иначе у вас будет утечка памяти в ваша программа, которая приведет к новым распределения не удается.
Нет, когда программа выходит ("закрывается"), динамически выделяемая память остается как есть
РЕДАКТИРОВАТЬ:
Читая другие ответы, я должен быть более точным. Деструкторы динамически выделяемых объектов не будут работать, но память все равно будет освобождена любой достойной ОС.
PS: первая строка должна читать
int* a = new int;
Когда ваш процесс завершается, ОС восстанавливает контроль над всеми ресурсами, которые он использовал, включая память. Однако это, конечно, не приведет к обязательному запуску деструкторов C ++, поэтому это не панацея от явного не освобождения указанных ресурсов (хотя это не будет проблемой для int
или других типов с noop dtors, конечно ;-).