У вас неопределенное поведение. Все может случиться. Нет смысла рассуждать, почему вы получаете эти результаты.
Тем не менее, вероятно, это происходит:
Первый - это непрерывный блок памяти (2 * 2 * sizeof (int)) в вашем стеке, где arr[3][3]
означает чтение данных из 3 * 3 * sizeof (int) байтов после начала этого блока.
Другой - один блок памяти (2 * sizeof (int *))) в куче, содержащей два указателя, указывающие на два отдельных блока памяти в куче (каждый 2 * sizeof (int)), где arr[3][3]
означает чтение данных из 3 * sizeof (int *) байтов после этого первого блока памятиинтерпретируйте все, что вы там найдете, как адрес памяти, а затем прочитайте данные из 3 * sizeof (int) байтов после этого адреса.