访问二维数组时,将其视为一维数组访问是否合法?

15

可能是重复问题:
是否可以将二维数组视为连续的一维数组?


考虑以下代码:

int array2d[10][10];
int *array1d = array2d[0];
我从未听说过此实现无法工作,但通过array1d访问和操作array2d是否合法?标准的哪个部分允许这样做?标准中是否有任何防止实现在第二级数组之间插入额外空间或填充的内容(虽然不需要,但还是要问一下)?
附加问题:是否有一种方法可以将array2d作为int[100]访问,而不需要使用reinterpret_cast 或者C风格的转换?

3
报名参加 C++ 模糊代码大赛了吗? :) - ScarletAmaranth
1
int* array1d = array2d[0];” 不是更加直接明了吗? - ildjarn
@ildjarn:确实如此,我肯定不习惯将数组转换。 - K-ballo
@ildjarn 你是指 &array2d[0] 对吧? - Eitan T
显示剩余4条评论
2个回答

6
如果我没记错的话,标准将这个作为官方未定义行为的例子,但基本上总是有效的。[编辑:这是我想到的:C99,§J.2(未定义行为):

  • 数组下标超出范围,即使对象似乎可以通过给定下标进行访问(例如lvalue表达式a [1] [7],给定声明int a [4] [5])

我不完全确定是否适用,因为你正在获取数组开头的地址并将其转换为底层类型的简单指针。]

数组必须是连续的,因此不能在数组元素之间插入任何填充。无论您有一个int数组还是一个数组的数组,都是如此。


0

这确实是合法的。标准明确规定多维数组只是比一维数组更大而已。我手头没有确切引用,但我知道这是真的。


我最近查阅了关于二维数组布局的标准文献(答案在这里)。但是,我不确定其中说一个数组T[n]占用确切的空间大小为n * sizeof(T)的部分在哪里。 - Jon
基本上,第一句引用中的“包含”让我有点紧张。为什么不使用更强的措辞呢?“包含”只是给出了一个下限。 - Jon
2
@Jon C++2003,§5.3.3/2:sizeof:当应用于数组时,结果是数组中所有字节的总数。这意味着n个元素的数组大小是元素大小的n倍。 - Robᵩ
拥有保证 sizeof(T[n]) == n * sizeof(T)(确实存在)并不足以保证行为是正确的。那么别名分析呢?在 OP 的代码中,array1dint[10] 数组内部的迭代器——现在假设有一个 int* p = array2d[1];。优化器(将跟踪这些指针从哪里初始化)将对 array1dp 访问是否允许别名感兴趣。C++ 作为一种语言不仅仅是汇编语言,而且是编码者和实现之间的契约。 - Luc Danton
这里没有别名违规。有 n * m 个整数,您可以使用 int* 合法地指向其中任何一个,并且它们保证是连续的,因此您可以增加指针以移动到下一个。 - Puppy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接