Определение char data;
резервирует место для одного char
.
char *ptr = &data;
устанавливает ptr
для указания на это char
.
Пробел в ptr+1
равен не зарезервировано для вашего использования, и ни стандарты C, ни стандарты C ++ не определяют, что произойдет, если вы попытаетесь его использовать.
Определение char data[3];
зарезервирует место для трех char
. Тогда char *ptr = data;
установит ptr
для указания на первый из этих char
. То есть ptr
будет иметь адрес &data[0]
, а *ptr
будет data[0]
.
Тогда ptr+1
будет указывать на следующее char
; он будет иметь адрес &data[1]
, а *(ptr+1)
будет data[1]
.
Как правило, вы должны использовать арифметику указателя c только для доступа к месту, которое, как вы знаете, зарезервировано для вашего использования. (Могут быть исключения или пояснения к этому в специальном коде, таком как код в ядре операционной системы, чтобы иметь дело с отображением памяти или кодом в специальном оборудовании. Вам не нужно рассматривать такие возможности в обычных пользовательских программах.)
Компилятор, как правило, не препятствует доступу к недействительным адресам. В некоторых случаях это может произойти, когда он обнаруживает ссылку вне пределов. Как правило, это происходит только в текущих компиляторах с простыми выражениями, где полные определения видны компилятору, а ссылки по существу используют постоянные индексы.
Операционная система может препятствовать доступу к некоторым недопустимым адресам. Тем не менее, он будет препятствовать доступу к недействительным адресам либо потому, что они вообще не сопоставлены с вашей программой, либо они сопоставлены только для чтения, но вы попытались записать их (или некоторые другие комбинации, такие как попытка чтения execute- только память). Операционная система не помешает вам неправильно обращаться к адресам, которые сопоставлены и доступны вашей программе. Например, вычисление неверного значения указателя и использование его в назначении для изменения памяти может привести к изменению данных, необходимых вашей программе для других функций.