-6

I have the following program

#include<stdio.h>

int main() {
    int a[3][3]={{1,2,3},
                {4,5,6},
                {7,8,9}};

    printf("%p\n",a);
    printf("%p\n",a[0]);
    printf("%p\n",*(a+0));
}

And it gives me the following output:

6356716
6356716
6356716

I was expecting that, given a base address such as 6356716 then *(6356716+0) would yield the value inside that location (i.e, 1).

So, if an array name is equivalent to a pointer to its first value like in above expression, printing 'a' should print the pointer to its first value i.e a[0](which itself decays to its 1st element at location 6356716). In that case, why does dereferencing not work here, and *(a+0) evaluates to *(6356716+0)?

Norman Gray
  • 11,978
  • 2
  • 33
  • 56
tusharK3411
  • 85
  • 1
  • 3

3 Answers3

1

a is an array of 3 arrays of 3 int. When used in an expression other than as an operand of sizeof, unary &, or _Alignof, it is automatically converted to a pointer to its first argument, which is an array of 3 int. If you correctly print this pointer, it will show the address of that array of 3 int.

a[0] is the first element in a, so it is an array of 3 int. When used in an expression, with the same exceptions as above, it is automatically converted to a pointer to its first element, which is an int. If you correctly print this pointer, it will show the address of that int.

Since an array is simply a sequence of objects stored contiguously, an array starts at the same place that its first element does. Therefore, the results of printing a and a[0] show the same address.

*(a+0) is the same as a[0], so printing it has the same result.

You should not use %u to print address. Printing pointers with %u has undefined behavior. It might appear to work in your implementation in some circumstances, but it will break in other circumstances. To print an address, use %p with a pointer converted to void * or const void *:

printf("%p\n", (const void *) a);
printf("%p\n", (const void *) a[0]);
printf("%p\n", (const void *) *(a+0));
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

When used in

printf("%u\n", a);
printf("%u\n", a[0]);

a decays to the pointer to the first element of a and a[0] decays to the pointer to the first element of a[0]. Equivalently, you could use:

printf("%u\n", &a[0]);
printf("%u\n", &a[0][0]);

From a object type point of view, &a, &a[], and&a[0][0] are completely different pointer types. However, if you look at the memory layout of a 2D array, you will realize that, from a purely numerical point of view, &a == &a[] == &a[0][0].

Also, "%u" is not the correct format for printing pointers. You should use "%p".

printf("%p\n", a);
printf("%p\n", a[0]);
Killzone Kid
  • 6,171
  • 3
  • 17
  • 37
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • UB: wrong printf pointer format. Sending the address is the same but the referenced objects are not (have different types). – 0___________ Aug 17 '18 at 20:30
  • @P__J__, you are right. I was addressing just the core question but I have updated the answer a bit. – R Sahu Aug 17 '18 at 20:56
0

First thing you need to understand is that a 2D array is treated as an array of arrays and all the elements of 2D array are stored in continuous memory locations,Now the second thing to understand is that an array name actually gives the address of first element in it.So your first printf statement printf("%u\n",a);actually gives you the address of a[0],as a[0] is the first element in this 2D array.Now your second printf statement printf("%u\n",a[0]); gives you the address of a[0][0] , because a[0] is actually the name of first array in the 2D array.Now your last printf statement is printf("%u\n",*(a+0)); is actually the way a compiler internally treats array ,it is exactly same as the second one.As from the explanation it is clear that the three statements are referring to the same address but this does not mean that they are same thing ,the first statement has a different meaning as compared to second and third as explained above.Though the three statements are giving you the address of 1,which is the first element of the 2D array.

LocalHost
  • 910
  • 3
  • 8
  • 24