1
void main()
{
        int array[10] = {1,2,3,4,5,6,7};
        printf("%p\n",array);
}

Here, the system would allocate a memory in stack equivalent to 10 integers for the array. However, i dont think there is any extra memory allocate for the variable array, i presume array is a mnemonic for human understanding and coding purpose. If that is the case, how does the printf() in the statement - printf("%p\n",array); accept it as though it is a pointer variable?

This confusion becomes more evident as the dimension(s) of the array keeps increasing.

int main()
{
        int matrix[2][4] = {{11,22,33,99},{44,55,66,110}};
        printf("%p\n", matrix);
        printf("%p\n", matrix+1);
        printf("%p\n", *(matrix+1));
}

The ouput for one of the program execution was -

0x7ffd9ba44d10
0x7ffd9ba44d20
0x7ffd9ba44d20

So both matrix+1 and *(matrix+1), after indirection outputs the same virtual memory address. I understand why matrix+1 address is what it is displaying but i don't understand why *(matrix+1) is outputting the same address even after indirection!

Darshan L
  • 824
  • 8
  • 30

1 Answers1

5

Well arrays are not pointers. Most of the cases(the exceptions are sizeof,&operator, _alignof etc) - it is converted into (array decaying) pointer to first element.

So here matrix is converted (decay) into pointer to first element - which is int (*)[4] when passed to printf.

Now dissect one by one, matrix+1 will point to the second element of the 2d array which is the 2nd element of the 2d array (That's why they are sizeof(int)*4 times apart.

In the third case they are same, because matrix+1 is of type int (*)[4] and when you dereference it you get int[4] basically the same address as that of before.


There is one thing to keep in mind - with pointers there are two things

  • It's value
  • It's type.

Two pointers may have the same value but their type may be different. Here also you saw that.

It (decaying) is mentioned in standard 6.3.2.1p3:-

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type 'array of type' is converted to an expression with type 'pointer to type' that points to the initial element of the array object and is not an lvalue.

Also you print the address in wrong manner (this is one of the case you would use casting).

printf("%p",(void*)matrix);

To make things a bit more clear:-

matrix is basically an object int[2][4] which decayed in the cases you have shown to int(*)[4]. You might wonder what is it that makes matrix+1 point to the second element of the array - the thing is pointer arithmetic is dicated by thing it points to. Here matrix as decayed into pointer to first element (int(*)[4]) it will move by an size of 4 ints.

user2736738
  • 30,591
  • 5
  • 42
  • 56
  • "decay" is understood, but the C-standard uses the term "converted". (only exceptions to conversion are when used with `sizeof`, `_alignof` and unary `&` operators) – David C. Rankin Jan 21 '18 at 03:33
  • No, your fine, but you do so good with the C-standard links, I figured you would be using "converted" – David C. Rankin Jan 21 '18 at 03:35
  • If there is no extra space allocated for the array variable - `array` or `matrix` then how does the compiler does all the pointer arithmetic ? – Darshan L Jan 21 '18 at 04:57
  • @DarshanL.: I don't get your question to be honest - pointer arithmetic is dictated by the object it points to. That is what it will be. I don't know which space you are talking about. Try to understand a bit - at first it seems a bit difficult but the rule is same. – user2736738 Jan 21 '18 at 04:59