Is it guaranteed that the type T[x][y] has the same memory layout as T[x*y] in C? Is it guaranteed that the type T[x][y] has the same memory layout as T[x*y] in C? c c

Is it guaranteed that the type T[x][y] has the same memory layout as T[x*y] in C?


An array of M elements of type A has all its elements in contiguous positions in memory, without padding bytes at all.This fact is not depending on the nature of A.

Now, if A is the type "array of N elements having type T", then each element in the T-type array will have, again, N contiguous positions in memory. All these blocks of N objects of type T are, also, stored in contiguous positions.

So, the result, is the existence in memory of M*N elements of type T, stored in contiguous positions.

The element [i][j] of the array is stored in the position i*N+j.


Let's consider

T array[size]; array[0]; // 1

1 is formally defined as:

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))

per §6.5.2.1, clause 2 taken from the standard C draft N1570. When applied to multi-dimensional arrays, «array whose elements are arrays», we have:

If E is an n-dimensional array (n ≥ 2) with dimensions i × j × ... × k, then E (used as other than an lvalue) is converted to a pointer to an (n − 1)-dimensional array with dimensions j × . . . × k.

Therefore, givenE = T array[i][j] and S = array[i][j], S is first converted to a pointer to a one-dimensional array of size j, namely T (*ptr)[j] = &array[i].

If the unary * operator is applied to this pointer explicitly, or implicitly as a result of subscripting, the result is the referenced (n − 1)-dimensional array, which itself is converted into a pointer if used as other than an lvalue.

and this rule applies recursively. We may conclude that, in order to do so, the n-dimensional array must be allocated contiguously.

It follows from this that arrays are stored in row-major order (last subscript varies fastest).

in terms of logical layout.

Since char [12] has to be stored contiguously and so has to char [3][4], and since they have the same alignment, they should be compatible, despite they're technically different types.


What you're referring to as types are not types. The type T you mention in the title would be (in this case) a pointer to a char.

You're correct that when it comes to structs, alignment is a factor that can lead to padding being added, which may mean that your struct takes up more bytes than meets the eye.

Having said that, when you allocate an array, the array will be contiguous in memory. Remember that when you index into an array, array[3] is equivalent to *(array + 3).

For example, the following program should print out 12:

#include <stdio.h>int main() {    char array[4][3];    printf("%zu", sizeof(array));    return 0;}