Многомерные массивы - это действительно одномерные массивы с небольшим количеством синтаксического сахара.
Инициализация для ptr не была адресом. Это должно было быть
int *ptr[4] = { &arr[0][0], &arr[1][0], &arr[2][0], &arr[3][0]};
Вы также можете оставить 4 и просто использовать
int *ptr[] = { &arr[0][0], &arr[1][0], &arr[2][0], &arr[3][0]};
Я внес несколько изменений в ваш код ниже. Обратите внимание на два раздела с printf. Они должны помочь продемонстрировать, как значения на самом деле выкладываются в память.
#define MAJOR 3
#define MINOR 4
int arr[MAJOR][MINOR]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int (*ptr)[4];
int *p = &arr[0][0];
// init ptr to point to starting location in arr
for(i = 0; i < MAJOR; i++) {
ptr[i] = &arr[i][0];
}
// print out all the values of arr using a single int *
for(i = 0; i < MAJOR * MINOR; i++) {
printf(" %d", *(p + i) );
}
for(i = 0; i < MAJOR; i++) {
for(j = 0; j < MINOR; j++) {
printf( " %d", *(p + i * MAJOR + j) );
}
printf("\n");
}