2013-10-20 3 views
0

Динамическое выделение памяти на C++, конечно, может быть выполнено с использованием new или delete. Если курсор, динамически распределенный с использованием new, больше не нужен в ходе программы на C++, delete может использоваться для динамического освобождения памяти компьютера. Я думаю, если моя память послужит мне правильно, то Stroustrep в одной из своих книг на C++ упоминает, что malloc и alloc в C предоставляют компилятору, а не программисту возможность «освобождать» или «создавать» память в отличие от объекта -ориентированный «новый» и «удалить». Если я не удалю указатель, тогда я столкнусь с довольно коварной утечкой памяти, что не очень хорошо.Утечки памяти, перегрузка оператора присваивания, новое, удаление и C++

Тем не менее, просто удаление указателя - как примечание Каррано, Хельмана и Вероффа (CHV) на страницах 151-153 во втором издании «Стены и зеркала» - не избавляется от указателя. Скорее удалите пустоты, содержимое указателя все же оставляет указатель где-то в памяти компьютера.

В любом случае CHV тогда скажет, что указатель должен быть установлен на NULL после использования delete, чтобы избавиться от этой «удаленной» конструкции.

Является ли оператор назначения перегружен в этом случае, чтобы принять NULL в качестве логического значения? Другими словами, компилятор говорит компьютеру, что это ложь, что указатель должен существовать в памяти, что означает, что я говорю компилятору, чтобы физически остановить кучу электронов, занимающих двухбитное пространство от моего компьютера ? Я что-то упустил?

+5

Итак ... много ... путаница ... –

+5

Это как одна из тех научных трудов тролля. –

+0

У меня создалось впечатление, что «NULL == 0» будет трактоваться как ИСТИНА, что означает, что NULL является синонимом FALSE, что подразумевает, что указатель превращается в конструкцию типа «Boolean», как только она заканчивается таким образом. Я думал, что 0 «закрывает» электронные ворота, а «1» означает, что ворота открыты. Я ошибаюсь? – fishermanhat

ответ

4

просто удалить указатель не избавляется от указателя

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

В любом случае, ХВ, то говорят, что указатель должен быть установлен в NULL после использования удалить, чтобы избавиться от этого «удален» построить

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

Является ли оператор присваивания перегруженным в этом случае принимать NULL как логическое значение?

No, NULL не является логическим значением, это константа нулевого указателя; значение специального указателя, которое не указывает ни на что.

Другими словами, компилятор говорит компьютеру, что это неверно, что указатель должен существовать в пространстве памяти, а это означает, что я говорю компилятор физически остановить кучу электронов, занимающих два бита пространство от моего компьютера?

Er, что? Нет, это просто говорит указателю, чтобы он не указывал ни на что. Это, конечно, не мешает никаким электронам занимать какие-либо пространства.

Я пропустил что-то здесь?

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

0

Указатель на уклонение с nullptr или NULL используется для предотвращения сбоев при двойном удалении, а не для освобождения памяти, которую фактически занимает указатель (указатель, а не память, на которую он указывает). Единственный момент, когда фактический указатель прекращает существование, - это конец области.

1

Немного истории может помочь. Во-первых, был С, с таНос и др .: например

char *ptr = malloc(100); 
strcpy(ptr, "hello, world!"); 
free(ptr); 
printf("%s\n", ptr); /* BAD - but will PROBABLY print "hello, world!" */ 

таНос выделяет 100 байт, в STRCPY населенную его, и свободный() освобождает его. То, что связано с «deallocate», просто означает, что эта память теперь будет доступна для повторного использования другим вызовом malloc.

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

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

free(ptr); 
ptr = NULL; 
printf("%s\n", ptr); /* Now we get a NULL pointer exception - which is what we want */ 

Мы хотим Null-указатель-исключение, так как после free() мы не должны использовать значение ptr.

С C++ все эти аргументы одинаковы. delete делает еще несколько вещей, чем бесплатно - в первую очередь это вызывает деструкторы объектов и т. д., но базовые же. Указатели не сбрасываются, а память все еще лежит вокруг - и вы хотите знать, обращается ли вы к памяти, которая не выделена для вас, и лучший способ сделать это - установить ваши указатели на нуль при удалении объекта.

0

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

void someFunc() 
{ 
    int* ptr; 

}//ptr dies after this bracket 

Так всегда помните, чтобы освободить память, указатель указывает на, прежде чем она выходит из области видимости или никогда вам придет иметь возможность доступа к нему снова!

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