int a[A][B];
int* p = a[i]; //i<A-1
then what's the actual operation of the sentence below?
p++;
p+=B;
int a[A][B];
int* p = a[i]; //i<A-1
then what's the actual operation of the sentence below?
p++;
p+=B;
p++
-> Go to next column in the matrix
p+=B
-> Go to the next row (at the same column) in the matrix.
The answer is quite simple if you draw the a[A][B] matrix in memory form, aka a vector and start with p pointing at the beginning of a[i] and then apply those operations.
After the initialization, a has storage for A*B ints and p points to the B*i'th one (0-based). The later operations make it point to the B*(i+1)+1'th one.
p = a[A-1]
is the same as
p = &a[A-1][0]
so
p++
results in
p == &a[A-1][1]
and then doing
p+=B
will result in
p == &a[A-1][1+B] == &a[A][1] // outside allocated memory
For multidimensional arrays, one has to remember that the dimensions are applied from left to right, which makes it somewhat easier to visualise. for example:
int p[A][B][C];
This will be built as :
[][]--[][][][]--[][]_ _ _[][]--[][] [][]--[][][][]--[][]_ _ _[][]--[][]
|---A----||---A----| |---A----|---|---A----||---A----| |---A----|
|---------------A*B---------------| |---------------A*B---------------|
|---------------------------------A*B*C---------------------------------|
so if you have a p[i][j][k], i'ts actually (p+i+Bj+BCk)
Just to further the conversation (although I can't actually respond to cbailey's post directly without enough reps...)
There's a big difference between declaring a multi-dimensional array on the stack, and on the heap.
As abelenky might be getting at, declaring a multi-dimensional array on the stack will always result in contiguous memory. I believe that the C standard actually states this somewhere, but even if it doesn't, every compiler on the planet will ensure that it is contiguous. Meaning that at the end of the day, you might as well be using a single dimension array, because the compiler will convert to that anyways.
In terms of being safe when using multi-dimensional arrays, regardless of whether they are allocated on the heap or the stack, you'd not want to iterate over them the way the original poster did.
This is sort of a meta-answer, aimed at much at Justicle as at the original poster.
Arrays degenerate into pointers, but they are not the same thing. Just because the syntax to get at a[3][7][1] is the same if a is a pointer-to-pointer-to-pointer-to-int versus an array-of-array-of-array-of-int doesn't mean that the actual operation is the same.
You can make an array of any type (of well defined size). Array dereference syntax and pointer syntax are the same, such that
a[i] == *(a+i) == i[a]
no matter what array type a is.
All the answers to questions in this thread can be derived from this.
int a[3][2][17]; //a is an array of length 17.
int (*b)[3][2] = a[5]; //b is a pointer to the fifth element of a
int (*c)[3] = b[1]; //c points to the first element of b.
b += 1; // b now points to the sixth element of a. (c is unchanged)
c += sizeof(*b); // c points to the first element of b again.
Note that none of this would work if a were not contiguous. If it didn't work then arrays of arrays would work differently than arrays of anything else.