Хранение неверного указателя автоматически неопределенное поведение?
====================================================================

Очевидно, что разыменование недействительного указателя вызывает неопределенное поведение. Но как насчет простохранения неверный адрес памяти в переменной указателя?

Рассмотрим следующий код:

Выражение`begin - 1` оценивает неверный адрес памяти. Обратите внимание, что мы на самом деле не разыменовываем этот адрес - мы просто используем его в арифметике указателей, чтобы проверить, действителен ли он. Тем не менее, мы все равно должны загрузить неверный адрес памяти в регистр.

Итак, это неопределенное поведение? Я никогда не думал, что это так, поскольку большая часть арифметики с указателями, похоже, полагается на подобные вещи, а указатель на самом деле является целым числом. Но недавно я услышал, что даже сам процесс загрузки недопустимого указателя в регистр является неопределенным поведением, поскольку некоторые архитектуры автоматически выдают ошибку шины или что-то подобное, если вы это сделаете. Может кто-нибудь указать мне на соответствующую часть стандарта C или C ++, которая решает эту проблему в любом случае?

 и он делает его неопределенным из-за упущения. Это определяет случай`ptr + I` на 6,5,6 / 8 для

Если операнд-указатель указывает на элемент объекта массива, и массив достаточно велик, результат указывает на смещение элемента от исходного элемента, так что разность индексов результирующего и исходного элементов массива равна целочисленному выражению.Кроме того, если выражение P указывает на последний элемент объекта массива, выражение (P) +1 указывает один за последним элементом объекта массива, а если выражение Q указывает на один последний элемент последнего элемента массива, выражение (Q) -1 указывает на последний элемент объекта массива.Ваш случай не подходит ни к одному из них. Ваш массив не достаточно велик, чтобы иметь`-1` отрегулируйте указатель так, чтобы он указывал на другой элемент массива, и ни один из результатов или исходный указатель не указывали один за другим.



[Обоснование C99](http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf) [Сек. 6.5.6, последние 3 абзаца] объясняет, почему стандарт одобряет добавление`1` на указатель, который указывает на последний элемент массива (`p+1`):

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

и почему`p-1` не подтверждено:

В случае p-1, с другой стороны, весь объект должен быть размещен до массива объектов, через которые проходит p, поэтому декрементные циклы, которые выходят за пределы массива, могут потерпеть неудачу. Это ограничение позволяет сегментным архитектурам, например, размещать объекты в начале диапазона адресуемой памяти.

Так что, если указатель`p` указывает на объект в начале диапазона адресуемой памяти, который подтверждается этим комментарием, затем`p-1` будет генерировать недостаточное количество.

Обратите внимание, что целочисленное переполнение является примером стандарта для неопределенного поведения [сек. 3.4.3], так как это зависит от среды перевода и операционной среды. Я полагаю, что легко увидеть, что эта зависимость от среды распространяется и на недостаточное указание.

Вот почему стандарт явно делает его неопределенным поведением [в 6.5.6 / 8], как отмечено другими ответами здесь. Чтобы процитировать это предложение:

Если и операнд-указатель, и результат указывают на элементы одного и того же объекта массива или один после последнего элемента объекта массива, оценка не должна вызывать переполнение; в противном случае поведение не определено.

Смотрите также [сек. 6.3.2.3, последние 4 абзаца] обоснования C99, в котором дается более подробное описание того, как недействительные указатели могут быть сгенерированы, и какие эффекты это может иметь.



выражение`begin - 1` делаетне вывести неверный указатель Это неопределенное поведение. Вам не разрешено выполнять арифметику указателей за пределами массива, над которым вы работаете. Таким образом, недопустимым является вычитание, а не сохранение полученного указателя.



ей. Помещение значения несопоставленного адреса в такой регистр может привести к сбою. Целочисленное переполнение / переполнение может привести к сбою. Поскольку C стремится работать на широком спектре платформ, указатели предоставляют механизм для безопасного программирования небезопасных схем.

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

Конечно, пример - плохой стиль, и нет веских причин для этого.



[принятый ответ](https://stackoverflow.com/questions/1866461/why-should-i-not-try-to-use-this-value-after-delete-this/1866543#1866543) в[это тесно связанный вопрос](https://stackoverflow.com/questions/1866461/why-should-i-not-try-to-use-this-value-after-delete-this), Присвоение недопустимого указателя переменной, сравнение недопустимого указателя, приведение недопустимого указателя вызывает неопределенное поведение.



$ 5.объекта массива или один после последнего элемента объекта массива, поведение не определено.75)»

Резюме, оно не определено**даже если вы не разыменовываете указатель**.



 поведению. У меня нет здесь стандарта C, но я вижу «недопустимые указатели» в Обосновании:<http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf>