Является ли указатель гарантией сохранить его значение после `delete` в С++?

Вдохновленный этот вопрос.

Предположим, что в коде С++ у меня есть правильный указатель и правильно delete он. Согласно стандарту С++, указатель станет недействительным (3.7.3.2/4 - функция освобождения сделает недопустимыми все указатели, ссылающиеся на все части освобожденного хранилища).

По крайней мере, в большинстве реализаций он сохраняет значение и будет хранить точно тот же адрес, что и раньше delete, однако используя значение undefined поведение.

Является ли стандарт гарантией того, что указатель сохранит его значение или это значение может быть изменено?

Ответ 1

Нет, это не гарантировано, и реализация может законно назначить ноль операнду lvalue на delete.

Bjarne Stroustrup надеялся, что реализация решит это сделать, но не многие из них.

http://www.stroustrup.com/bs_faq2.html#delete-zero

Ответ 2

Если по какой-либо причине вы хотите убедиться, что переменная указателя не изменяется на delete, напишите:

delete p + 0;

Ответ 3

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

Ответ 4

Подпись глобального оператора удаляет, как это требуется стандартом 3.7.3.2/2:

Каждая функция освобождения возвращает void, а ее первый параметр должен быть недействительным *.

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

Ответ 5

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

Что вы можете поставить под сомнение, скажете ли вы, что вы делали свою собственную проверку утечки, поэтому вы написали функцию, чтобы удалить указатель с карты после того, как вы сделали удаление. Это будет использовать std:: less, который, как гарантируется, будет работать с указателями, которые не указывают в пределах диапазона, и предположительно будут работать с указателями, указывающими на то, что память больше не действительна.

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

Как и в случае с стандартом, если значение, которое вы передаете для удаления, не является l-значением, оно гарантировано поддерживает одно и то же значение, но если оно является значением l, оно определяется реализацией.

Ответ 6

Считайте, как бы вы проверяли или полагались на любой ответ "да" или "нет"? Вы не можете. Или вы можете, но результатом этой проверки (кроме nullpointer) является Undefined Поведение.

Невозможно проверить ненулевое значение после delete, поэтому вопрос вообще бессмысленен.

Кроме того, аргумент delete может быть выражением rvalue, поэтому вопрос не имеет смысла.

Приветствия и hth.,