Мне всегда было интересно, почему автоматическая установка указателя на NULL после удаления не входит в стандарт. Если об этом позаботиться, то многих сбоев из-за неправильного указателя не произойдет. Но, сказав это, я могу придумать пару причин, по которым стандарт ограничил бы это:
Производительность:
Дополнительная инструкция может снизить
delete
производительность.Может быть, из-за
const
указателей.С другой стороны, стандарт мог бы что-то сделать для этого особого случая, я думаю.
Кто-нибудь знает точные причины, по которым этого нельзя допустить?
Во-первых, для установки значения null потребуется переменная, хранящаяся в памяти. Это правда, что обычно у вас есть указатель на переменную, но иногда вы можете захотеть удалить объект по только что рассчитанному адресу. Это было бы невозможно с «аннулирующим» удалением.
Затем идет перформанс. Вы могли написать код таким образом, чтобы указатель выходил за пределы области действия сразу после удаления . Заполнение его нулевым значением - пустая трата времени. А C ++ - это язык с идеологией «не нужно? Тогда за это не нужно платить».
Если вам нужна безопасность, к вашим услугам широкий выбор умных указателей или вы можете написать свои собственные - лучше и умнее.
источник
delete (ptr + i)
У вас может быть несколько указателей, указывающих на эту память. Это создало бы ложное чувство безопасности, если бы указатель, который вы указали для удаления, был установлен в нуль, а все другие указатели - нет. Указатель - это не что иное, как адрес, число. С таким же успехом это может быть int с операцией разыменования. Я хочу сказать, что вам также придется сканировать каждый указатель, чтобы найти те, которые ссылаются на ту же самую память, которую вы только что удалили, а также обнулить их. Было бы сложно сканировать все указатели для этого адреса и обнулять их, потому что язык не предназначен для этого. (Хотя некоторые другие языки структурируют свои ссылки для достижения аналогичной цели другим способом.)
источник
Указатель может быть сохранен более чем в одной переменной, установка одной из них в NULL все равно оставит недействительные указатели в других переменных. Так что вы на самом деле ничего не выиграете, вы, скорее всего, создаете ложное чувство безопасности.
Кроме того, вы можете создать свою собственную функцию, которая будет делать то, что вы хотите:
источник
Потому что на самом деле в этом нет необходимости, и потому что для этого потребуется удалить указатель на указатель, а не просто указатель.
источник
delete
используется в основном в деструкторах, и в этом случае установка значения NULL для члена бессмысленна. Несколькими строками позже, при закрытии}
, член больше не существует. В операторах присваивания за удалением в любом случае следует присваивание.Кроме того, это сделает следующий код незаконным:
источник
Вот еще одна причина; предположим, что delete устанавливает свой аргумент в NULL:
Должен ли бар быть установлен на NULL? Можете ли вы это обобщить?
источник
Если у вас есть массив указателей, а ваше второе действие - удалить пустой массив, тогда нет смысла устанавливать для каждого значения значение null, когда память собирается освободить. Если вы хотите, чтобы он был нулевым ... напишите ему null :)
источник
C ++ позволяет вам определять собственный оператор new и delete, чтобы, например, они использовали ваш собственный распределитель пула. Если вы сделаете это, то можно будет использовать новые и удалить вещи, которые не являются строго адресами, но говорят индексы в вашем массиве пула. В этом контексте значение NULL (0) может иметь юридическое значение (относящееся к первому элементу в пуле).
Таким образом, если удалить, автоматически установив NULL для своего аргумента, не всегда означает - установить недопустимое значение. Недопустимое значение не всегда может быть NULL.
источник
Философия C ++ - «плати, только если пользуешься». Думаю, это может ответить на ваш вопрос.
Также иногда у вас может быть собственная куча, которая будет восстанавливать удаленную память ... или иногда указатель, не принадлежащий какой-либо переменной. Или указатель хранится в нескольких переменных - можно обнулить только одну из них.
Как видите, у него много проблем и возможных проблем.
источник
Автоматическая установка указателя на NULL не решит большинство проблем с неправильным использованием указателя. Единственный сбой, которого можно избежать, - это попытка удалить его дважды. Что, если вы вызовете функцию-член для такого указателя? Он все равно выйдет из строя (при условии, что он обращается к переменным-членам). C ++ не запрещает вам вызывать какие-либо функции с указателями NULL, и не должен делать этого с точки зрения производительности.
источник
Я вижу, как люди дают странные ответы на этот вопрос.
ptr = NULL; Как такое простое утверждение может вызвать задержку производительности?
Другой ответ гласит, что у нас может быть несколько указателей, указывающих на одно и то же место в памяти. Конечно можем. В этом случае операция удаления для одного указателя сделает только этот указатель NULL (если удаление делает указатель NULL), а другой указатель будет отличным от NULL и указывать на свободную ячейку памяти.
Решением для этого должно было быть то, что пользователь должен удалить все указатели, указывающие на одно и то же место. Внутренне он должен проверить, освобождена ли уже память, чем не освобождена. Только сделайте указатель NULL.
Страуструп мог бы спроектировать удаление для работы таким образом. Он думал, что программисты позаботятся об этом. Поэтому он проигнорировал.
источник