子数组是否保证线性分配?
Are Sub-Arrays Guaranteed to be Allocated Linearly?
我知道 is in violation of the reinterpret_cast
rules但它也假定子数组将被线性分配。
我认为这并不能保证,但是当我搜索标准时,我发现我的信心在动摇。如果我静态分配一个二维数组,像这样:
int foo[][4] = { { 5, 7, 8 },
{ 6, 6 },
{},
{ 5, 6, 8, 9 } };
我可以假设所有元素都是线性分配的吗?也就是说如果foo[0]
在地址0x00000042,会:
foo[1]
位于地址 0x00000052
foo[2]
位于地址 0x00000062
foo[3]
位于地址 0x00000072
这些地址是十六进制的,是的,它们为具有 sizeof(int) == 4
的 4 元素子数组提供 space;它们可能会也可能不会被零初始化。
Are Sub-Arrays Guaranteed to be Allocated Linearly?
是的。无论数组的元素是子数组还是非数组对象,都保证在内存中是连续存储的。
为了完整起见,这里是标准报价:
[dcl.array]
- [snip] An object of array type contains a contiguously allocated non-empty set of N subobjects of type T. [snip]
T
为数组也不例外
So we know this isn't guaranteed to be the case for const char[4]
.
相反,我们确实知道 对 char[4]
对象有保证,就像对其他类型有保证一样。
For example: const char first[] = "foo"; char foo[][4] = {"bar", "foo", "", "baz"}
first
在内存中会这样存储:
{'f', 'o', 'o', '[=10=]'}
foo
会这样存储:
{'b', 'a', 'r', '[=11=]', 'f', 'o', 'o', '[=11=]', '[=11=]', '[=11=]', '[=11=]', '[=11=]', 'b', 'a', 'z', '[=11=]'}
So why would you say this is guaranteed for ints?
保证 int[4]
、char[4]
和您能想象到的任何其他类型。
来自C语言标准ISO/IEC9899§6.2.5Types/p20(强调我的):
An array type describes a contiguously allocated nonempty set of
objects with a particular member object type, called the element type.
同样来自C语言标准ISO/IEC9899§6.5.2.1/p3数组下标(强调我的):
Successive subscript operators designate an element of a
multidimensional array object. If E
is an n-dimensional array (n >=
2) with dimensions i x j x . . . x k
, then E
(used as other than
an lvalue) is converted to a pointer to an (n - 1)
-dimensional array
with dimensions j 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).
从上面我们可以得出结论,二维数组实际上是一个以行优先顺序存储的一维数组。
因此,可以安全地假设子数组的元素连续存储在内存中。
我知道reinterpret_cast
rules但它也假定子数组将被线性分配。
我认为这并不能保证,但是当我搜索标准时,我发现我的信心在动摇。如果我静态分配一个二维数组,像这样:
int foo[][4] = { { 5, 7, 8 },
{ 6, 6 },
{},
{ 5, 6, 8, 9 } };
我可以假设所有元素都是线性分配的吗?也就是说如果foo[0]
在地址0x00000042,会:
foo[1]
位于地址 0x00000052foo[2]
位于地址 0x00000062foo[3]
位于地址 0x00000072
这些地址是十六进制的,是的,它们为具有 sizeof(int) == 4
的 4 元素子数组提供 space;它们可能会也可能不会被零初始化。
Are Sub-Arrays Guaranteed to be Allocated Linearly?
是的。无论数组的元素是子数组还是非数组对象,都保证在内存中是连续存储的。
为了完整起见,这里是标准报价:
[dcl.array]
- [snip] An object of array type contains a contiguously allocated non-empty set of N subobjects of type T. [snip]
T
为数组也不例外
So we know this isn't guaranteed to be the case for
const char[4]
.
相反,我们确实知道 对 char[4]
对象有保证,就像对其他类型有保证一样。
For example: const char first[] = "foo"; char foo[][4] = {"bar", "foo", "", "baz"}
first
在内存中会这样存储:
{'f', 'o', 'o', '[=10=]'}
foo
会这样存储:
{'b', 'a', 'r', '[=11=]', 'f', 'o', 'o', '[=11=]', '[=11=]', '[=11=]', '[=11=]', '[=11=]', 'b', 'a', 'z', '[=11=]'}
So why would you say this is guaranteed for ints?
保证 int[4]
、char[4]
和您能想象到的任何其他类型。
来自C语言标准ISO/IEC9899§6.2.5Types/p20(强调我的):
An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type.
同样来自C语言标准ISO/IEC9899§6.5.2.1/p3数组下标(强调我的):
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).
从上面我们可以得出结论,二维数组实际上是一个以行优先顺序存储的一维数组。
因此,可以安全地假设子数组的元素连续存储在内存中。