Все проблемы возникают из-за использования &a
, который является указателем на «массив из пяти целых чисел», так что арифметика указателей (когда вы думаете с точки зрения адресов) «масштабируется» на sizeof(a)
( например, 20, если int
- 4 байта, и компилятору не требуется заполнение для выравнивания - разумные гипотезы, хотя, конечно, далеко не определенные.
Итак, после
int *ptr = (int *)(&a+1);
int *t = (int *)(&a -1);
ptr
- указатель на int по адресу памяти "sizeof (a) больше, чем адрес a", и t
аналогично для "sizeof (a) меньше, чем адрес a". Поэтому ...:
printf("%d %d %d \n", *(a+1), *(ptr-1), *(t+1));
Каким должен быть результат?
Вполне возможно, нарушение сегментации, в противном случае 20
, за которым следуют два совершенно произвольных целочисленных значения. Поскольку ptr
и t
являются указателями на int
, адресное арифметическое масштабирование для их -1
и +1
не не компенсирует то, что было сделано для &a
(масштабирование с точки зрения памяти адреса указываются на sizeof(int)
, а не sizeof(a)
!), поэтому ptr-1
и t+1
указывают на (предположительно ;-) int
с, что соответственно "через несколько int
с после окончания a
"и" за несколько int
с до начала a
".
Нет никакого способа узнать, есть ли на этих произвольных адресах какая-либо память, к которой процессу разрешено обращаться (откуда возможны нарушения сегментации), и, если какая-либо доступная память есть там, какая ее содержимое, «воспринимаемое как int
», возможно, может быть.
Редактировать : @caf указывает, что ptr - 1
является не недопустимым - он правильно указывает на последний элемент a
; поэтому вывод (если нет ошибки сегментации, которую @NullUserException считает маловероятной, но с этим мы не согласны ;-) начнется с 20 50
перед третьим, «произвольным» мусором. Точка, согласно стандарту C, является действительной для вычисления (хотя и не для использования) указателя «только один конец» массива, и размера массива должен точно соответствовать длине этого массива по размеру его элементов (заполнение допускается для типа элемента, если необходимо, и если да, то оно отображается в собственном размере элемента, но не для массива в целом). Тонкий, но важный; -).