Multi-dimensional arrays are really one dimensional arrays with a little syntaxic sugar.
The initialization you had for ptr wasn't an address. It should have been
int *ptr[4] = { &arr[0][0], &arr[1][0], &arr[2][0], &arr[3][0]};
You can also leave the 4 out and just use
int *ptr[] = { &arr[0][0], &arr[1][0], &arr[2][0], &arr[3][0]};
I made a few modifications to your code below. Note the two sections with the printf. They should help to demonstrative how the values are actually laid out in memory.
#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");
}