Вот как int[2][2]
выглядит в памяти:
int[2] int[2]
То есть, за массивом сразу же следует другой массив.
Вот как int[2]
выглядит в памяти:
int int
То есть, за int сразу же следует другое int.
Итак, вот как выглядит int[2][2]
в памяти:
int int int int
^ ^
| |___ this is arr[1][1]
|
|____ this is p[1], assuming sizeof(int*) == sizeof(int)
Если вы приведете arr
к int**
, я назову результат p
. Тогда это указывает на ту же память. Когда вы делаете p[1][1]
, вы не получаете arr[1][1]
. Вместо этого программа читает значение на p[1]
, корректирует его на величину типа int и разыменовывает его . Если во втором int содержится, скажем, значение «21», то вы только что попытались разыменовать указатель «25» (если int
равно 4 байта). Это не правильно.
Массивы - это не то же самое, что указатели, а двумерные массивы определенно не то же самое, что указатели на указатели.