Different Pointer Arithmetic Results when Taking Address of Array
CPointersLanguage LawyerC Problem Overview
Program:
#include<stdio.h>
int main(void) {
int x[4];
printf("%p\n", x);
printf("%p\n", x + 1);
printf("%p\n", &x);
printf("%p\n", &x + 1);
}
Output:
$ ./a.out
0xbff93510
0xbff93514
0xbff93510
0xbff93520
$
I expect that the following is the output of the above program. For example:
x // 0x100
x+1 // 0x104 Because x is an integer array
&x // 0x100 Address of array
&x+1 // 0x104
But the output of the last statement is different from whast I expected. &x
is also the address of the array. So incrementing 1 on this
will print the address incremented by 4. But &x+1
gives the address incremented by 10. Why?
C Solutions
Solution 1 - C
x -> Points to the first element of the array.
&x ->Points to the entire array.
Stumbled upon a descriptive explanation here: http://arjunsreedharan.org/post/69303442896/the-difference-between-arr-and-arr-how-to-find
SO link: https://stackoverflow.com/questions/8916656/why-is-arr-and-arr-the-same
Solution 2 - C
In case 4 you get 0x100 + sizeof x
and sizeof x
is 4 * sizeof int
= 4 * 4 = 16 = 0x10.
(On your system, sizeof int
is 4).
Solution 3 - C
An easy thumbrule to evaluate this is:
Any pointer on increment points to the next memory location of its base type.
The base type of &x here is *int (p)[4] which is a pointer to array of 4 integers.
So the next pointer of this type will point to 16 bytes away (assuming int to be 4 bytes) from the original array.
Solution 4 - C
Even though x
and &x
evaluate to the same pointer value, they are different types. Type of x
after it decays to a pointer is int*
whereas type of &x
is int (*)[4]
.
sizeof(x)
is sizeof(int)*4
.
Hence the numerical difference between &x
and &x + 1
is sizeof(int)*4
.
It can be better visualized using a 2D array. Let's say you have:
int array[2][4];
The memory layout for array
is:
array
|
+---+---+---+---+---+---+---+---+
| | | | | | | | |
+---+---+---+---+---+---+---+---+
array[0] array[1]
| |
+---+---+---+---+---+---+---+---+
| | | | | | | | |
+---+---+---+---+---+---+---+---+
If you use a pointer to such an array,
int (*ptr)[4] = array;
and look at the memory through the pointer, it looks like:
ptr ptr+1
| |
+---+---+---+---+---+---+---+---+
| | | | | | | | |
+---+---+---+---+---+---+---+---+
As you can see, the difference between ptr
and ptr+1
is sizeof(int)*4
. That analogy applies to the difference between &x
and &x + 1
in your code.
Solution 5 - C
Believe it or not, the behaviour of your program is undefined!
&x + 1
is actually pointing to just beyond the array, as @i486's answer cleverly points out. You don't own that memory. Even attempting to assign a pointer to it is undefined behaviour, let alone attempting to dereference it.