Удалить NULL, но нет ошибки компиляции

Я запутался, почему следующий код C ++ может компилироваться. Почему вызов для удаления метода 0 не приводит к ошибке ?!

int *arr = NULL;     // or if I use 0, it's the same thing      
delete arr;

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

13.10.2009 03:03:55
Код не компилируется - вам нужен тип для указателя (например, void), а не просто квалификатор; это не (старый) С.
Jonathan Leffler 13.10.2009 04:16:39
5 ОТВЕТОВ
РЕШЕНИЕ

Язык C ++ гарантирует, что delete p ничего не сделает, если p равно NULL.

Для получения дополнительной информации ознакомьтесь с разделом 16.8,9 здесь :

19
13.10.2009 03:08:58
Тем не менее, вопрос был в том, почему код компилируется ; не почему нет ошибки во время выполнения.
Josh 13.10.2009 03:18:51
В C ++ разрешено удалять указатель NULL, поэтому компилятор в порядке.
Jim Buck 13.10.2009 03:22:31
Разрешается ли разыменование null тоже? Как насчет переполнения стека? Покажите мне компилятор, который выдает ошибки при таких условиях ...
Josh 13.10.2009 03:25:39
Что касается компилятора, все это допустимо. Конечно, во время выполнения может быть другое мнение ...
Jeremy Friesner 13.10.2009 03:42:51
Вау, Джош, может я просто читаю неправильно, но ты говоришь довольно оборонительно или что-то в этом роде. Удаление нуля это нормально, ничего не делает.
GManNickG 13.10.2009 03:50:39

NULL и 0 не одно и то же. В C ++ вы должны использовать 0.

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

0
13.10.2009 03:07:54
На самом деле, в C ++ NULL определяется как 0. Более того, NULL и 0 - это стилистическая дискуссия, для которой нет однозначного ответа.
rlbond 13.10.2009 03:14:48
Нет абсолютно никакой причины предпочитать 0 над NULL в C ++. Хотя по какой-то причине время от времени всплывает рекомендация «использовать 0 в C ++». Я не знаю, откуда взялась эта городская легенда, но, опять же, нет ничего плохого в использовании NULL в C ++, и, как правило, для удобства чтения NULL предпочтительнее, чем 0.
AnT 13.10.2009 03:30:10
Страуструп предпочитает 0 вместо NULL: research.att.com/~bs/bs_faq2.html#null
ChrisW 13.10.2009 03:32:36
Мне кажется, что NULL - лучший стиль, хотя бы потому, что когда вы ищете проблемы с указателями, вы можете искать их. В программе, которая использует 0 вместо NULL, поиск 0 даст вам и 0, и указатель, и целочисленное использование, а ненужные дополнительные результаты потребуют больше времени для сканирования.
Jeremy Friesner 13.10.2009 03:39:07
Ответ не является ни: nullptr. Поскольку пока нет nullptr, вы можете создать этот тип и решить проблему. Тем не менее, я считаю NULLуродливым. Это все заглавные буквы (уродливые), навязчивые (уродливые) и ick.
GManNickG 13.10.2009 03:52:30

Хотя ваш пример тривиален, у компилятора нет способа узнать (во время компиляции) значение указателя.

Вы также можете разыменовать null во время компиляции:

// this code compiles
Object* pObject = 0;
pObject->SomeMethod();

Компиляторы не созданы для обработки таких типов ошибок во время компиляции.

И большинство (все?) Реализации имеют «delete 0» как неоперацию. Этот код должен работать нормально:

Object* pObject = new Object();
delete pObject;
pObject = 0;
delete pObject;

Хотя я не уверен на 100% в этом :)

0
13.10.2009 03:08:36
Вы правы. У меня возникли проблемы с двойным удалением ... или, может быть, я воображаю вещи?
Josh 13.10.2009 03:12:34
Любой компилятор C ++, который рассматривает «delete NULL» как что-либо кроме no-op, является ошибочным компилятором. Язык C ++ указывает, что удаление указателя NULL безопасно. (С другой стороны, два раза вызов delete для одного и того же указателя, отличного от NULL, вызовет у вас проблемы)
Jeremy Friesner 13.10.2009 03:41:20
@ Джереми Фризнер: Я понимаю вашу точку зрения, но с педантичной точки зрения, «удалить NULL» является плохо сформированным. «NULL» в C ++ требуется для обозначения целого нуля, а «delete» не может быть применен к целому 0. «delete NULL» так же плохо сформирован, как «delete 0», то есть очень :)
AnT 13.10.2009 04:32:28
... 'delete (int *) NULL', с другой стороны, является законным и действительно должен быть неактивным.
AnT 13.10.2009 04:33:39

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

int *ptr_A = &a;
ptr_A = NULL;
delete ptr_A;

Обычно это удобно делать:

...
delete ptr;
ptr = NULL;
1
13.10.2009 03:13:29
Обычно плохая практика - обнулять указатель. Причина в том, что указатели должны быть заключены в классы. deleteзатем происходит в деструкторах, после чего указатель больше не существует или в присваивании, в котором указатель получает новое значение. Следовательно, обычно не существует методов, которые бы указывали на NULL. Единственное очевидное исключение - это «необязательная» часть объекта, которая больше не нужна, но подумайте boost::optional<T>об этом.
MSalters 13.10.2009 09:44:09

Это де-факто стандарт в языках C и C ++ (и не только в них), что процедуры освобождения ресурсов должны принимать аргументы нулевого указателя и просто ничего не делать. На самом деле, это довольно условное соглашение. Итак, настоящий вопрос здесь: почему это удивляет вас? Что заставляет вас думать, что это должно привести к ошибке? Более того, с чего вы взяли, что он не должен компилироваться ???

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

1
13.10.2009 03:27:30
s / de facto / de jure / - см. цитату из стандарта ISO.
MSalters 13.10.2009 09:45:59