关于数据对齐的困惑

时间:2011-09-22 14:24:20

标签: c++ visual-c++ alignment

假设一个像这样定义的结构:

struct S{
    char a[3];
    char b[3];
    char c[3];
};

那么 printf(“%d”,sizeof(S))的输出是什么?在我的Vc ++ 2008表达式的编译器上,输出是9.我感到困惑......我想结果是12,但事实并非如此。编译器不应该将结构与4或8对齐吗?

6 个答案:

答案 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; };。然后在ab之间有一个字节内部填充以正确对齐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字节对齐的。这意味着它不需要填充。