到目前为止,我认为它是,但在我了解到编译器可能填充数据以使其符合架构要求时,例如我有疑问.所以我想知道一个char[4][3]
内存布局是否相同char[12]
.编译器可以在char[3]
部件之后放置填充以使其对齐,这样整个数组实际上需要16个字节吗?
背景故事,库的一个函数在char*
参数中占用一堆固定长度的字符串,因此它需要一个没有paddig的连续缓冲区,字符串长度可以是奇数.所以我认为我声明了一个char[N_STRINGS][STRING_LENGTH]
数组,然后方便地填充它并通过将其传递给函数传递给它char*
.到目前为止似乎有效.但我不确定这个解决方案是否可移植.
A类型的M元素数组的所有元素都在内存中的连续位置,根本没有填充字节.这个事实并不取决于A的性质.
现在,如果A是类型"具有类型T的N个元素的数组",则T型数组中的每个元素将再次具有存储器中的N个连续位置.所有这些类型为T的N个对象的块也存储在连续的位置.
因此,结果是存在于T*的M*N个元素的存储器中,存储在连续的位置.
[i][j]
数组的元素存储在该位置i*N+j
.
我们考虑一下
T array[size]; array[0]; // 1
1
正式定义为:
下标operator []的定义与之
E1[E2]
相同(*((E1)+(E2)))
根据§6.5.2.1,第2条取自标准C草案N1570.当应用于多维数组时,«元素为数组的数组»,我们有:
如果E是具有维度的n维数组(n≥2)
i × j × ... × k
,那么E(用作除左值之外)被转换为指向具有维度的(n-1)维数组的指针j × . . . × k.
因此,给定
E = T array[i][j]
和S = array[i][j]
,S
首先转换为指向一维数组大小的指针j
,即T (*ptr)[j] = &array[i]
.
如果将unary*运算符显式地应用于此指针,或者作为预订的结果隐式应用,则结果是引用的(n-1)维数组,如果用作除左值之外的其他数据本身将转换为指针.
并且此规则以递归方式应用.我们可以得出结论,为了这样做,n-dimensional
必须连续分配数组.
由此得出,数组以行主要顺序存储(最后一个下标变化最快).
在逻辑布局方面.
由于char [12]
必须连续存储并且必须存储char [3][4]
,并且因为它们具有相同的对齐,所以它们应该是兼容的,尽管它们在技术上是不同的类型.