Firstly, you said: &a
means the address of a[0]
so &a+1
should be the address of a[1] ? No you are wrong. &a
means address of a
not a[0]
. And &a+1
means it increments by whole array size not just one elements size and a+1
means address of a[1]
.
Here
int a[5] = {1,2,3,4,5};
lets assume base address of a
is 0x100
--------------------------------------
| 1 | 2 | 3 | 4 | 5 |
--------------------------------------
0x100 0x104 0x108 0x112 0x116 ..
LSB
|
a
When you are doing
int *ptr = (int*)(&a+1);
Where ptr
points ? first (&a+1)
performed and it got increments by whole array size i.e
(&a+1) == (0x100 + 1*20) /* &a+1 here it increments by array size */
== 0x120
So now ptr
points to
--------------------------------------
| 1 | 2 | 3 | 4 | 5 |
--------------------------------------
0x100 0x104 0x108 0x112 0x116 0x120
a |
ptr points here
Now when you print like
printf("%d %d", *(a+1), *(ptr-1));
Here
*(a+1) == *(0x100 + 1*4) /* multiplied by 4 bcz of elements is of int type*/
== *(0x104) /* value at 0x104 location */
== 2 (it prints 2)
And
*(ptr-1) == *(0x120 - 1*4)
== *(0x116) /* prints value at 0x116 memory location */
== 5
Note :- Here
int *ptr = (int*)(&a+1);
type of &a
is of int(*)[5]
i.e pointer to an array of 5 elements but you are casting as of int*
type, as pointed by @someprogrammerdude it breaks the strict aliasing and lead to undefined behavior.
Correct one is
int *ptr = a+1;