Reputation: 469
I have come across a code which goes like :
#include <stdio.h>
int main(void)
{
int a[5] = { 1, 2, 3, 4, 5};
int *ptr = (int*)(&a + 1);
int *ptr2 = (int*) &a;
ptr2 +=1 ;
printf("%d %d %d \n", *(a + 1),*(ptr - 1) ,*ptr2 );
return 0;
}
The pointer arithmetic does it for me except this line :
int *ptr = (int*)(&a + 1);
Is it undefined behaviour ?
Why do we get 5
on dereferencing *(ptr - 1)
?
Upvotes: 0
Views: 563
Reputation: 59
For an array of n elements of type T, then the address of the first element has type ‘pointer to T’; the address of the whole array has type ‘pointer to array of n elements of type T’;
int *ptr = (int*)(&a + 1); //&a-> address whole array, size=20 bytes,
//ptr=&a+1: next element =adress of a +20 bytes.
//ptr - 1 = address of a +16 = address of last a's element = address of 5
Upvotes: 0
Reputation: 49373
Try it out!
int a[5] = {1, 2, 3, 4, 5};
printf("%#x, %#x, %#x, %#x\n", a, &a, a+1, &a+1);
0xbfa4038c, 0xbfa4038c, 0xbfa40390, 0xbfa403a0
So what does that tell us?
0xbfa4038c == 0xbfa4038c
which means a == &a
. This is the address of the first element in the array or a[0]
.
We know that the size of an int is 4, and you know that *(a+1)
== a[1]
(the second element in the array) and this is proven by:
0xbfa4038c + 0x4 = 0xbfa40390
which means a + one int = address of the next element
Thus if we see &a+1 == 0xbfa403a0
, that means we're ((0xa0-0x8c)/4)
= 5 elements into the array. You know that a[5]
is invalid, so that means we're one passed the end of the array.
so if you take:
int *ptr = (int*)(&a + 1); //one passed last element in the array
printf("%d",*(ptr - 1));//back up one, or last element in the array and deference
That's why you get 5
Upvotes: 2
Reputation: 399723
The size of a
is "5 int
s". So &a + 1
refers to the first memory location past all of a
, since the pointer arithmetic is done in units of the size of a
.
Upvotes: 3