我知道这个答案违反了reinterpret_cast
规则,但它也假定子阵列将是线性分配的。
我相信这是不能保证的,但是当我搜索标准时,我发现自己的信心动摇了。如果我静态分配了一个2D数组,则是这样:
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元素子阵列提供空间;他们可能也可能不会被零定为零。
子阵列是否保证线性分配?
是。数组的元素是子阵列还是非阵列对象,保证它们连续存储在内存中。
为了完整性,这是标准报价:
[dcl.array]
- [SNIP]数组类型的对象包含A 连续分配的非空的n个n子对象集。[SNIP]
T
是数组的情况。
所以我们知道这不是
const char[4]
的情况。
相反,我们确实知道此是为char[4]
对象保证,就像其他类型的保证一样。
例如:const char first [] =" foo; quot;;char foo [] [4] = {; bar;;
first
将像这样存储在内存中:
{'f', 'o', 'o', ' '}
foo
将像这样存储:
{'b', 'a', 'r', ' ', 'f', 'o', 'o', ' ', ' ', ' ', ' ', ' ', 'b', 'a', 'z', ' '}
那么,为什么要保证这是INT的?
可以保证int[4]
,char[4]
和您可以想象的任何其他类型。
来自C语言标准ISO/IEC 9899 §6.2.5类型/p20 (重点是mine ):
一个数组类型描述了一套连续的非空置集 对象带有特定成员对象类型,称为元素类型。
也来自C语言标准ISO/IEC 9899 §6.5.2.1/p3数组订阅(重点是我的):
连续的下标操作员指定一个元素 多维数组对象。如果
E
是n维数组(n> = 2)尺寸i x j x . . . x k
,然后是E
(用作其他 LVALUE)转换为(n - 1)
的指针 - 维数阵列 尺寸j x . . . x k
。如果应用了一元*
操作员 明确或暗中订阅了该指针的结果 结果是指向(n - 1)
二维数组,本身 如果用作LVALUE,则将其转换为指针。 从此遵循的是,数组以行订单存储(最后 下标不同)。
从上面的情况下,我们可以得出结论,2D数组实际上是一个以行订单存储的1D数组。
因此,可以肯定地假设子阵列的元素连续存储在内存。