Here's a more illustrative example:
#include <iostream>
using namespace std;
int main() {
int a[2][3] = { {4, 3, 7}, {2, 6, 9} };
int * b = (int *)a + 4;
cout << *b << endl; // output is 6
int c[2 * 3] = { 4, 3, 7, 2, 6, 9 };
int * d = c + 4;
cout << *d << endl; // output is 6
}
b
and d
are both pointers to ints. They are pointing to the base of their respective arrays plus four. With both double- and single-dimensional arrays, this is the memory corresponding to '6'.
It's that C/C++ is doing the math of 2 * 3 behind your back, and allocating space on the stack of 6 * sizeof(int) (ignoring padding). So the pointer arithmetic works out the same.
I'm guessing you ran in to trouble with something like:
int * b = a + 4;
star.cpp:7:15: error: cannot initialize a variable of type 'int *' with an rvalue of type 'int (*)[3]'
int * b = a + 4;
^ ~~~~~
1 error generated.
Which led you try the int ** b
. This isn't a pointer to an int in a double-dimensional array, it's a pointer to a pointer to an int.
Not really sure what the goal is, but a much simpler implementation would be:
#include <iostream>
using namespace std;
int main() {
int a[2][3] = { {4, 3, 7}, {2, 6, 9} };
int b = a[1][1];
cout << b << endl; // output is 6
}