Это, конечно, неопределенное поведение (по здравому смыслу, и формулировки стандарта).
Насколько стандарт идет, 3,8/5 довольно конкретно о том, что разрешено и о том, что это не так:
[...] после того, как время жизни объекта закончилась и перед тем хранилище, в котором объект занят, повторно используется или освобождается, любой указатель, который ссылается на место хранения, в котором находится или находится объект, может использоваться, но только ограниченным образом [...] и с использованием указателя, как если бы указатель были типа void *, четко определен.
[...] разрешено [...], как описано ниже.Программа имеет неопределенное поведение, если:
- ...
- [...] используются в качестве операнда static_cast
, за исключением того, когда преобразование является указатель на сорт void
, или указатель на сорта void
и впоследствии указатель либо сорта или сорта char
unsigned char
- [...] используется в качестве операнда dynamic_cast
хранения объекта заканчивается в конце области на 3.7.3/1 (на практике это, скорее всего не верно, фрейм стека, вероятно, будет сброшен в конце functio n, но формально вот что бывает). Следовательно, разыменование не происходит после окончания срока службы , но до освобождение хранилища. Это происходит после освобождение памяти.
Особые условия, при которых вы можете разыменовать указатель, в любом случае не применяются (то же самое верно для любых аналогичных абзацев с тем же предварительным условием, как 3.8/6).
Далее, при условии, что предыдущий пункт не соответствует действительности, это допустимо только для разыменования указателя в качестве сорта void*
или бросить его сорта char
(знаком или без знака) до разыменования. Другими словами, вы находитесь , а не разрешено смотреть на int
, как если бы это было int
. Как указано в 3.8/5, int*
действительно всего лишь void*
после времени жизни объекта. Это означает, что разыменование его как int*
эквивалентно выполнению броска (не явно, но все же).
Хотелось бы, чтобы эта попытка вызвала ошибку, но я думаю, что это очень сложная задача для обнаружения компилятором. Сам указатель хорошо и жив, и он был безопасно получен путем принятия адреса действительного объекта, который, вероятно, почти невозможно диагностировать.
Я считаю, что 'p' все равно укажет на место памяти, где' n' было, но вы не знаете, что там будет. – mstbaum
@mstbaum и как это связано с вопросом? – Slava
@remyabel (Мой предыдущий удаленный комментарий спросил, не означает ли «предсказать результаты» UB.) Возможно, я не понимаю, что такое неопределенное поведение. Мое рассуждение, вероятно, похоже на mstbaum's, поскольку мы не знаем, что находится в этом месте в памяти, поэтому мы не можем предсказать результаты. Разве этого недостаточно? Должен ли я искать его в стандарте, чтобы быть уверенным? – eigenchris