2010-06-05 3 views
1

На Learn C++, они написали это, чтобы освободить память:C++: Вопрос об освобождении памяти

int *pnValue = new int; // dynamically allocate an integer 
*pnValue = 7; // assign 7 to this integer 
delete pnValue; 
pnValue = 0; 

Мой вопрос: «Является ли последнее утверждение необходимо правильно освободить память, укомплектовать?»

Я думал, что указатель *pnValue все еще находился в стеке, а new не имеет никакого смысла для указателя. И если он находится в стеке, он будет очищен, когда приложение покинет область действия (где объявлен указатель), не так ли?

+1

'pnValue' автоматически выделяется (в стеке), да. То, на что это указывает, - нет. Вы удаляете pnValue', чтобы удалить динамически выделенную память, на которую указывает, и указатель выходит из области действия позже. – GManNickG

+0

@GMan: Спасибо! Я не был уверен в этом. Спасибо –

ответ

2

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

if(ptr) 
{ 
    delete ptr; 
    ptr = NULL; 
} 

Так установить указатель на NULL гарантирует, что не будет удален дважды.

Наконец, вы можете найти код, подобный этому:

void foo(bar *ptr) 
{ 
    if(!ptr) throw Exception(); // or return, or do some other error checking 
    // ... 
} 

И вы, вероятно, хотите, чтобы проверить безопасность, чтобы ударить.

+7

'if' здесь полностью избыточно .- Просто« delete ptr; ptr = 0; '. Удаление нулевого указателя является no-op, поэтому, когда вы назначаете нуль, даже проверка 'if' больше не требуется. –

+0

Whoops неправильно читают его. –

+2

Я думаю, что можно утверждать, что после удаления его полезно установить значение null. Если вы удалили указатель, это значение должно быть неактуальным, потому что * last * вещь, которую вы делаете с указателем, удаляет ее. Если у вас все еще есть это, вы делаете это неправильно. Не только это, вам все равно не нужно его удалять, это должно быть сделано для вас (это связано с тем, что вам не нужно беспокоиться об использовании его снова.) Если у меня заканчивается плохой дизайн и сохраняются указатели вокруг, что я не нужно, по крайней мере, значение, отличное от нуля, может привести к сбою и сообщить, что есть проблема с моим дизайном, ... – GManNickG

3

Это не обязательно, но всегда рекомендуется указывать указатели на NULL (0), когда вы закончите с ними. Таким образом, если вы передадите его функции (что будет ошибкой), скорее всего, это приведет к ошибке, а не к попытке работать с недопустимой памятью (что значительно облегчает отслеживание ошибки). И это также упрощает условия.

+0

~ Да, но разве это не в обратном порядке? Вы действительно установите его после удаления? – jcolebrand

+5

Лучше еще идея - убедиться, что указатель выходит из области действия при его освобождении. У вас нет бесплатных указателей, разбросанных по всему вашему коду. Оберните их в классы RAII или умные указатели. – jalf

+0

@ drache: Вы имеете в виду 'p = 0; delete p; '? Это не имеет никакого смысла и приводит к утечке памяти. – fredoverflow

Смежные вопросы