На самом деле, результат, который вы видите, равен , потому что ваш компилятор использует UB, когда вы обращаетесь к массиву за пределами.
Когда вы обращаетесь к своей переменной через aa[i][j]
, компиляторвычисляет доступный адрес следующим образом (C использует мажорный порядок строк макет памяти):
address_of(aa)+2*i+j # 2 elements in a row
Но что, если i
или / и j
находятся вне диапазона?Что должен делать компилятор?
Если бы это был не UB, компилятор должен был бы выдать некоторый код, который проверяет диапазоны и выдает ошибку, если диапазоны были нарушены.
Тем не менее, поскольку этот случай равен UB, получившаяся в результате программа может делать все что угодно:
- форматировать свой жесткий диск
- отправлять смущающие сообщения из ваших аккаунтов
- crash
- просто примените приведенную выше формулу
Самый простой способ для программиста-компилятора - выбрать последний вариант, который подходит для всех известных мне компиляторов (но вы не имеете права предполагать, что этобудет иметь место в будущем - возможно, среднестатистический программист-компилятор выберет один из первых двух вариантов!).
В приведенной выше формуле адрес aa[0][2]
такой же, как и для aa[1][0]
(т.е. смещение 2
), которое объясняет результаты, которые вы видите.