I know this answer is in violation of the reinterpret_cast
rules but it also presumes that sub-arrays will be allocated linearly.
I believed this was not guaranteed, but as I search the standard, I find my confidence wavering. If I statically allocate a 2D array, like this:
int foo[][4] = { { 5, 7, 8 },
{ 6, 6 },
{},
{ 5, 6, 8, 9 } };
Am I allowed to assume that all elements will be allocated linearly? That is to say that if foo[0]
is at address 0x00000042, will:
foo[1]
be at address 0x00000052foo[2]
be at address 0x00000062foo[3]
be at address 0x00000072These addresses are in hex, and yes they are providing space for the 4-element sub-array with sizeof(int) == 4
; they may and may not be zero-initialized.
Are Sub-Arrays Guaranteed to be Allocated Linearly?
Yes. Whether the elements of the array are sub-arrays or non-array objects, they are guaranteed to be stored contiguously in memory.
For completeness, here is the standard quote:
[dcl.array]
- [snip] An object of array type contains a contiguously allocated non-empty set of N subobjects of type T. [snip]
There is no exception for the case when T
is an array.
So we know this isn't guaranteed to be the case for
const char[4]
.
On the contrary, we do know that this is guaranteed for char[4]
objects just like it is guaranteed for other types.
For example: const char first[] = "foo"; char foo[][4] = {"bar", "foo", "", "baz"}
first
would be stored like this in memory:
{'f', 'o', 'o', '\0'}
foo
would be stored like this:
{'b', 'a', 'r', '\0', 'f', 'o', 'o', '\0', '\0', '\0', '\0', '\0', 'b', 'a', 'z', '\0'}
So why would you say this is guaranteed for ints?
It is guaranteed for int[4]
, char[4]
and any other type that you can imagine.
From the C language standard ISO/IEC 9899 §6.2.5 Types/p20 (Emphasis Mine):
An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type.
Also from the C language standard ISO/IEC 9899 §6.5.2.1/p3 Array subscripting (Emphasis Mine):
Successive subscript operators designate an element of a multidimensional array object. If
E
is an n-dimensional array (n >= 2) with dimensionsi x j x . . . x k
, thenE
(used as other than an lvalue) is converted to a pointer to an(n - 1)
-dimensional array with dimensionsj x . . . x k
. If the unary*
operator is applied to this pointer explicitly, or implicitly as a result of subscripting, the result is the pointed-to(n - 1)
-dimensional array, which itself is converted into a pointer if used as other than an lvalue. It follows from this that arrays are stored in row-major order (last subscript varies fastest).
From the above we can conclude that a 2D array is actually a 1D array stored in row-major order.
Consequently, it's safe to assume that elements of a sub-array are stored contiguously in memory.
User contributions licensed under CC BY-SA 3.0