Cal*_*ius 13 c memory-alignment multidimensional-array language-lawyer
到目前为止,我认为它是,但在我了解到编译器可能填充数据以使其符合架构要求时,例如我有疑问.所以我想知道一个char[4][3]内存布局是否相同char[12].编译器可以在char[3]部件之后放置填充以使其对齐,这样整个数组实际上需要16个字节吗?
背景故事,库的一个函数在char*参数中占用一堆固定长度的字符串,因此它需要一个没有paddig的连续缓冲区,字符串长度可以是奇数.所以我认为我声明了一个char[N_STRINGS][STRING_LENGTH]数组,然后方便地填充它并通过将其传递给函数传递给它char*.到目前为止似乎有效.但我不确定这个解决方案是否可移植.
pab*_*977 10
A类型的M元素数组的所有元素都在内存中的连续位置,根本没有填充字节.这个事实并不取决于A的性质.
现在,如果A是类型"具有类型T的N个元素的数组",则T型数组中的每个元素将再次具有存储器中的N个连续位置.所有这些类型为T的N个对象的块也存储在连续的位置.
因此,结果是存在于T*的M*N个元素的存储器中,存储在连续的位置.
[i][j]数组的元素存储在该位置i*N+j.
我们考虑一下
T array[size];
array[0]; // 1
Run Code Online (Sandbox Code Playgroud)
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],并且因为它们具有相同的对齐,所以它们应该是兼容的,尽管它们在技术上是不同的类型.
您所说的类型不是类型。T您在标题中提到的类型将是(在本例中)指向字符的指针。
您是对的,当涉及到结构时,对齐是可能导致添加填充的一个因素,这可能意味着您的结构占用的字节数比看上去多。
话虽如此,当你分配一个数组时,该数组在内存中将是连续的。请记住,当您对数组进行索引时,array[3]相当于*(array + 3).
例如,以下程序应打印出12:
#include <stdio.h>
int main() {
char array[4][3];
printf("%zu", sizeof(array));
return 0;
}
Run Code Online (Sandbox Code Playgroud)