假设一个像这样定义的结构:
struct S{
char a[3];
char b[3];
char c[3];
};
那么 printf(“%d”,sizeof(S))的输出是什么?在我的Vc ++ 2008表达式的编译器上,输出是9.我感到困惑......我想结果是12,但事实并非如此。编译器不应该将结构与4或8对齐吗?
答案 0 :(得分:4)
sizeof
- 表达式的值取决于实现; C ++标准唯一保证的是它必须至少为9,因为你在char
中存储了9个struct
。
新的C ++ 11标准有一个alignas
关键字,但这可能无法在VC ++ 08中实现。查看编译器手册(参见例如__declspec(align(#))
)。
答案 1 :(得分:2)
S
中没有任何内容可以强制任何成员除了每个字节以外的对齐,因此编译器根本不需要添加任何填充。
答案 2 :(得分:1)
每个成员对齐的典型要求只要求结构本身与最大的成员类型对齐。由于所有成员类型都是char
,因此对齐方式为1
,因此不需要填充。 (对于数组,基本类型(所有删除的范围)都是重要的。)
考虑制作一个结构数组:你需要 all 该数组所有元素的成员对齐。但在你的情况下,这只是一个很大的字符串,所以不需要填充。
例如,假设在您的平台上sizeof(short) == 2
并且该对齐等于大小,并考虑struct X { char a; short b; char c; };
。然后在a
和b
之间有一个字节内部填充以正确对齐b
,但在c
之后还有一个字节终端填充,以便整个结构的大小为多个2
,最大的成员。这样,当您有一个数组X arr[10]
时,arr
的所有元素都将被单独正确对齐。
答案 3 :(得分:1)
首先,对齐是依赖于实现的,因此它将取决于编译器。
现在,请记住,对于静态分配的数组,不需要存储大小(标准不需要它),因此通常将数组的对齐作为其元素的对齐。
在这里,char[3]
因此具有1
的对齐方式,并且它们完美无缺。
答案 4 :(得分:1)
有一个编译器开关/ Zp,允许您设置默认的struct member对齐方式。还有一些其他方法可以在c语言中指定对齐方式。
查看此MSDN帖子了解详情:
http://msdn.microsoft.com/en-us/library/xh3e3fd0(v=vs.80).aspx
也许您的编译器正在使用其中一种设置?
答案 5 :(得分:0)
编译器对于如何对齐数据给出了相当广泛的自由度。然而,实际上,基准的对齐不会超过其大小。也就是说,char
必须是字节对齐的,而int
s和long
s通常是四字节对齐的。
此外,struct
符合其成员最严格的对齐要求。
因此,在您的示例中,最严格的内部对齐要求是1字节对齐,因此struct是1字节对齐的。这意味着它不需要填充。