数组的普通嵌套数组是否保证是连续的?

问题描述 投票:0回答:2

我假设嵌套的 std::array 不能假设内存是严格连续的:例如参见: 嵌套的 std::array 中的数据保证是连续的吗? 以及其他相关问题。 每个子数组的末尾可能有一些填充。 我找不到有关普通数组的等效信息。 是否能保证普通数组中的所有数据在内存中都是连续的? 例如:

uint8_t A[3][7];

可以肯定地说 A[1]-A[0] 是 7 吗?
附属问题:

sizeof
运算符在多维数组及其子数组之一上的行为应该是什么?

NB ISO/IEC JTC1 SC22 WG21 N4860 §9.3.3.4-9 规定:

[注:当多个“array of”规范相邻时,会创建多维数组类型;只有 指定数组边界的第一个常量表达式可以被省略。 [例子: int x3d[3][5][7]; 声明一个包含三个元素的数组,每个元素又是一个包含五个元素的数组,每个元素又是一个包含 七个整数。整个数组可以看作是一个三维整数数组,秩为 3 × 5 × 7。 任何表达式 x3d、x3d[i]、x3d[i][j]、x3d[i][j][k] 都可以合理地出现在表达式中。这 表达式 x3d[i] 等价于 *(x3d + i);在该表达式中,x3d 受数组到指针的约束 转换(7.3.2)并首先转换为指向二维数组的指针,该数组的秩为 5 × 7,该数组指向 x3d 的第一个元素。然后添加 i,这在典型的实现中涉及将 i 乘以 指针指向的对象的长度,即sizeof(int)×5 × 7。相加的结果 间接是一个左值,表示 x3d 的第 i 个数组元素(由五个数组组成的数组,每个数组有七个整数)。 如果还有另一个下标,则再次应用相同的参数,因此 x3d[i][j] 是表示第 j 个下标的左值 x3d 的第 i 个数组元素(七个整数的数组)的数组元素,并且 x3d[i][j][k] 是左值 表示x3d的第i个数组元素的第j个数组元素的第k个数组元素(整数)。 -结尾 示例]声明中的第一个下标有助于确定数组消耗的存储量 但在下标计算中不发挥其他作用。 ——尾注]

如果我理解正确,数据应该是连续的,但是“关于典型实现”部分让我感到困扰。所以我还需要确认。 (在这种情况下,我无法理解为什么 std::array 没有相同的保证)。

c++ multidimensional-array padding memory-alignment
2个回答
2
投票

sizeof A

 将等于 
3 * 7 * sizeof(uint8_t)

sizeof A[0]

 将等于 
7 * sizeof(uint8_t)

也就是说,

sizeof

 运算符对于任何数组都按预期工作。


关于

A[1]-A[0]

,由于
A[1]
A[0]
都是数组(类型为
uint8_t[7]
),因此它们将衰减为指向其第一个元素的指针。

所以这个表情真的是

&A[1][0] - &A[0][0]

因为每个子数组都是

7

 个元素,所以结果将是 
7
。请注意,无论元素类型如何,结果都是 
7
,因为结果以元素类型为单位,而不是字节。


最后回答一下标题中的问题:

[A]保证是连续的普通嵌套数组

是的,他们是。数组中没有填充。基本类型是什么、普通整数类型、结构或类对象或其他任何类型都没关系。


0
投票
是的,它应该是连续的,并且对于 sudo 代码

A[1] - A[0]

= 7,但它看起来像 
&
A[1][0] and &A[0][0]
,因为这会给出其实际地址位置。是 
7
,因为您可以通过 NB ISO/IEC JTC1 SC22 WG21 N4860 §9.3.3.4-9 的链接进行验证。

在 C++ 中,标准是将多维数组布置在内存中的连续块中。当它提到“典型实现”时,它使用该术语的原因是因为不同的数据类型具有不同的大小,因此这会改变它的大小和步幅,但它的行为仍然相同并且是连续的。

sizeof 运算符的行为也一致。当您将 sizeof 应用于多维数组时,它会给出整个数组占用的总大小,如果您将 sizeof 应用于其子数组之一,它将给出该子数组的大小。

对于你的例子来说,它是

3*7*sizeof(uint8_t)

 代表您的主阵列,
7*sizeof(uint8_t)
 代表您的子阵列。

现在说说为什么这与

std::array

不同。 
std::array
可以使用用户定义的自定义类型。这些类型可以具有自定义布局、尺寸和设置。因此 
std::array
 不可能保证其始终连续,因为它不知道将传入的类型。也就是说,如果您不使用像 uint8_t 这样的用户定义类型,它将按照我上面描述的方式运行。

© www.soinside.com 2019 - 2024. All rights reserved.