0
#include<stdio.h>
#include<conio.h>

int main()
{
    int a[3][4] = {1, 2, 3, 4, 4, 3, 2, 1, 7, 8, 9, 0};
    clrscr();    
    printf("%u \n",a);
    printf("%u, %u\n", a+1, &a+1);
    getch();
    return 0;
}

Output: 65502 65510 65526

How does this program work if sizeof(int)=2 and base address is 65502?

3 Answers3

1

When you use an array like a in an expression, it usually goes through “pointer decay” which means that you get a pointer to the first element of the array.

So, a has type int[3][4], and it decays to int (*)[4]. When you write a+1, you get the address of a[1]… which is sizeof(*a) bytes after a, which is sizeof(int)*4, which is 8 on your system.

When you use &, pointer decay does not happen. &a is not an array (it is already a pointer), so when you write &a+1, you get the address “one past the end” of a… which is sizeof(a) bytes after a, which is sizeof(int)*12, or 24 bytes on your system.

Note that, strictly speaking, the correct way to print pointers is with %p.

printf("%p\n", a);
printf("%p, %p\n", a+1, &a+1);

(Technically, you also have to cast to char * or void * but that’s hardly ever important.)

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
0

When you increment a pointer, it gets incremented in steps of the object size that the pointer can point to.

Type of a is int (*)[4]1) i.e. pointer to an object which is an array of 4 int type. So, the a + 1 will be a pointer obtained by adding size of array of 4 integers to pointer evaluated from a in the expression.

Type of &a is int (*)[3][4]1) i.e. pointer to an object which is a 2D array of int type with dimension 3x4. So, the &a + 1 will be a pointer obtained by adding size of 2D array of integers with dimension 3x4 to pointer evaluated from &a in the expression.


  1. When you access an array, it is converted to a pointer to first element (there are few exceptions to this rule).
H.S.
  • 11,654
  • 2
  • 15
  • 32
0
printf("%u, %u\n", a+1, &a+1);
  • a+1 - Here a decays into a pointer to its first element. In this case a pointer to an array of 4 int (type int (*)[4]). Have a look at What is array to pointer decay? for more information.

    Thereafter you increment this pointer by one. So, now the gained address is the one of one array element of 4 int of the 2D array forward, which matches to your output as sizeof(int) == 2 * 4 = 8. The difference between 65502 and 65510 is 8.


  • &a+1 - &a is first evaluated. When the & operator is applied, a doesn't decay to a pointer to its first element. Rather &a gains a pointer to the whole 2D array/ a pointer to an array of 3 arrays of 4 int (type int (*)[3][4]).

    Incrementing this pointer by one gets you one the size of the whole 2D array forward which also matches to your output because the difference between 65502 65526 is 24 which is correct because sizeof(int) == 2 * (3 * 4) = 24. (3 * 4) is the amount of elements in the 2D array.


Note: Printing a pointer with the %u format specifier invokes strictly seen undefined behavior. You need the %p format specifier for pointers and need to cast the pointer argument to void * to be standard-compliant.

printf("%p\n", (void*) a);
printf("%p, %p\n", (void*) a+1, (void*) &a+1);