It is my experience that a 2D C array is typically flattened in memory. Is this true for all compilers and platforms? Is casting a N-dimensional array to int*
and accessing it as arr_ptr[j + i*width]
safe across platforms/compilers?
Further detail follows. It is my understanding that a variable like
int data[2][3];
will be laid out in the stack/data segment as
lower addresses <----------------------------------------> higher addresses
| data[0][0] | data[0][1] | data[0][2] | data[1][0] | data[1][1] | data[1][2] |
For a function that takes such a type, we might want to avoid a call signature like
void handle2dArray(int arr[][10]);
Obviously there are ways to avoid this:
- malloc a int** instead
- use a 1D array and access with
arr[j + i*width]
But suppose for some reason we need to use an int[][SIZE]
. Is it safe to handle this 2D array by casting it to int*, as in the following?
void print2D(int *ptr, size_t dim0, size_t dim1) {
printf("2D Array: (%zu x %zu)\n", dim0, dim1);
for (size_t i = 0; i < dim0; i++) {
for (size_t j = 0; j < dim1; j++) {
printf("%d ", ptr[i*dim1 + j]);
}
printf("\n");
}
}
int main() {
int array2D[10][10];
print2D((int*)array2D, 10, 10);
}
In my experimenting, this appears to work for reasonable dimension sizes, number of dimensions, and compiler (gcc, clang, vc), on a few different computers with fairly standard architectures. Is this treatment of N-dimensional arrays something that is guaranteed by the C specifications, and is it considered a "proper" way to handle these situations?