Different Pointer Arithmetic Results when Taking Address of Array

CPointersLanguage Lawyer

C 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmohangrajView Question on Stackoverflow
Solution 1 - CthepaceView Answer on Stackoverflow
Solution 2 - Ci486View Answer on Stackoverflow
Solution 3 - CKowshikaView Answer on Stackoverflow
Solution 4 - CR SahuView Answer on Stackoverflow
Solution 5 - CBathshebaView Answer on Stackoverflow