I have the following code:
int ia[3][4] = { //
{0, 1, 2, 3}, //
{4, 5, 6, 7}, //
{8, 9, 10, 11} //
};
int (*p4)[4] = ia;
cout << \"(*(p4 + 0))
Postfix expressions have higher priority than unary expressions.
So this expression
*(p4 + 0)[3]
is equivalent to the expression
*( (p4 + 0)[3] )
As it is seen it is not the same as
( *(p4 + 0) )[3]
This expression *( (p4 + 0)[3] )
can be written just like *p4[3]
that is equivalent to *ia[3]
and due to the priority is considered like
*( ia[3] )
or like
ia[3][0]
The valid range for indices of the first dimension for the array ia
is [0, 2]
because the array is declared like
int ia[3][4] = { /*...*/ };
^^^
Thus expression ia[3]
tries to access memory beyond the array. As result the code snippet has undefined behavior.
Shortly speaking you should understand that these expressions
(*(p4 + 0))[3]
*(p4 + 0)[3]
that in turn are equivalent to the following pair of expressions
ia[0][3]
io[3][0]
are not equivalent due to the priorities of the operations.
I don't understand the last one how it arrives at 1.
Undefined behavior got you there.
Due to operator precedence (the array indexing operator binds tighter than the pointer dereference operator),
*(p4 + 0)[3]
is the same as:
*((p4 + 0)[3])
, which is the same as:
*(p4[3])
, which is the same as:
p4[3][0]
.
For your array. the valid indices for the first dimension are: 0
, 1
, and 2
. Accessing the array using the index value of 3
accesses memory beyond valid range, leading to undefined behavior.