Search code examples
cpointersmultidimensional-arrayimplicit-conversionpointer-arithmetic

Multidimensional array addressing C


In the following piece of code, I am getting the first two values of addresses same(call it x). I have run it on gcc compiler of ubuntu v18.04.4 LTS.

  int a[2][2] = {0};
  printf("%p %p %d\n", a, *a, **a);

This mean that:

  1. a contains the address x.
  2. a is pointing to the location x(as it is a pointer which is storing x).
  3. this means *a is stored in location x and it also contains the value x(as in the output of above code).
  4. now, on dereferncing *a i.e, **a, I am getting output as 0 which means that *a (whose value is x) is pointing to some location in which 0 is stored.

Now, from 1. , address of *a is x (as a points to *a and is storing x) and address of the number 0 is also x (as *a points to a[0][0] which is 0 and *a is storing x). So my question is what exactly is stored at the location x? Or have I mistaken something in making the conclusions?


Solution

  • Your assertion that a contains an address seems to indicate that you think a is a pointer. It is not a pointer but an array. They are related, but they are not the same thing.

    An array, in most contexts, decays to a pointer to its first member. In this case, this means that in an expression a is the same as &a[0] and *a is the same as a[0] which is the same as &a[0][0]. This also means that the address of an array is the same as the address of its first member, which is what you're seeing when you print a and *a.

    This would probably be better illustrated with a diagram:

          -----   -------   ----  ---
    0x100 | 0 |   a[0][0]   a[0]  a
          -----   -------   
    0x104 | 0 |   a[0][1]
          -----   -------   ----
    0x108 | 0 |   a[1][0]   a[1]
          -----   -------
    0x10c | 0 |   a[1][1]
          -----   -------   ----  ---
    

    From here, you can see that a starts at address 0x100 (x in your example) and contains a total of 4 int values. Also note that the subarray a[0] has the same address as a, as does the initial int element a[0][0].

    Generalizing this, the address of an array and the address of its first element, even though the types are different, are the same. So:

    • a is an array whose address is 0x100. It contains element of type int[2].
    • a[0] is an array whose address is 0x100. It contains element of type int.
    • a[0][0] is an int whose address is 0x100.