2

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?

Kaia
  • 862
  • 5
  • 21
  • 4
    Yes, contiguous row-major storage is mandated by the C standard, see for example the reference [here](https://stackoverflow.com/a/50300709). – dxiv Aug 21 '20 at 23:40
  • @dxiv Ah, perfect! If you want to write that as an answer I'd be happy to accept it; I'm not exactly sure how stackexchange etiquette works but I want you to get credit for the solution if you want it! – Kaia Aug 21 '20 at 23:50
  • 1
    Thank you, but the link in my comment only answers the first part of your question. There is a second part (otherwise I'd have voted to close it as a duplicate), which may still elicit more answers. – dxiv Aug 21 '20 at 23:57

0 Answers0