关于数据对齐的困惑
假设这样定义一个结构:
struct S{
char a[3];
char b[3];
char c[3];
};
那么 printf("%d", sizeof(S)) 的输出是什么?在我的 Vc++ 2008 表达式编译器上,输出是 9。我很困惑......我认为结果是 12,但事实并非如此。编译器不应该将结构对齐到 4 或 8 吗?
suppose a struct defined like this:
struct S{
char a[3];
char b[3];
char c[3];
};
then what will be the output of printf("%d", sizeof(S)) ? On My compiler of Vc++ 2008 expression, the output is 9. And I got confused... I suppose the result be 12, but it is not. Shouldn't the compiler align the structure to 4 or 8 ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
sizeof
表达式的值取决于实现; C++ 标准唯一保证的是它必须至少为 9,因为您在struct
中存储了 9 个char
。新的C++11标准有一个
alignas
关键字,但这可能无法在VC++08中实现。检查编译器手册(请参阅例如__declspec (对齐(#))
)。The value of the
sizeof
-expression is implementation-dependent; the only thing guaranteed by the C++ standard is that it must be at least nine since you're storing ninechar
's in thestruct
.The new C++11 standard has an
alignas
keyword, but this may not be implemented in VC++08. Check your compiler's manual (see e.g.__declspec(align(#))
).S
中没有任何内容会强制其任何成员除按字节对齐之外,因此编译器根本不需要添加任何填充。There's nothing in
S
that would force any of its members to be aligned other than per-byte so the compiler doesn't need to add any padding at all.首先,对齐取决于实现,因此它将取决于编译器。
现在,请记住,对于静态分配的数组,不需要存储大小(标准不要求存储),因此数组的对齐通常是其元素的对齐。
此处,
char[3]
的对齐方式为1
,并且它们被完美打包。First, the alignment is implementation dependent, so it will depend on the compiler.
Now, remember that for a statically allocated array, the size need not be stored (the standard does not require it is), therefore it is usual for the alignment of an array to be the alignment of its elements.
Here,
char[3]
thus has an alignment of1
, and they are perfectly packed.有一个编译器开关 /Zp,允许您设置默认的结构成员对齐方式。 C语言中还有一些其他的指定对齐的方法。
查看此 MSDN 帖子了解详细信息:
http:// msdn.microsoft.com/en-us/library/xh3e3fd0(v=vs.80).aspx
也许您的编译器正在使用这些设置之一?
There is a compiler switch, /Zp, that allows you to set the default struct member alignment. There are also some other methods for specifying alignment in the c language.
Check out this MSDN post for details:
http://msdn.microsoft.com/en-us/library/xh3e3fd0(v=vs.80).aspx
Maybe your compiler is using one of these settings?
每个成员对齐的典型要求仅要求结构本身与最大成员类型对齐。由于所有成员类型均为
char
,因此对齐方式为1
,因此不需要填充。 (对于数组,重要的是基本类型(删除所有范围)。)考虑创建一个结构数组:您希望该数组的所有元素的所有成员都对齐。但在你的情况下,这只是一大堆字符,所以不需要填充。
例如,假设在您的平台上
sizeof(short) == 2
并且对齐方式等于大小,并考虑struct X { char a;短b;字符c; };
。然后,在a
和b
之间有一个字节的内部填充,以正确对齐b
,而且在c
之后也有一个字节的终端填充> 这样整个结构体的大小就是最大成员大小2
的倍数。这样,当您有一个数组X arr[10]
时,arr
的所有元素都将单独正确对齐。The typical requirement that each member be aligned only requires that the structure itself be aligned to the largest member type. Since all member types are
char
, the alignment is1
, so there's no need for padding. (For arrays, the base type (all extents removed) is what counts.)Think about making an array of your structure: You'll want all the members of all the elements of that array to be aligned. But in your case that's just one large array of chars, so there's no need for padding.
As an example, suppose that on your platform
sizeof(short) == 2
and that alignment equals size, and considerstruct X { char a; short b; char c; };
. Then there's one byte internal padding betweena
andb
to alignb
correctly, but also one byte terminal padding afterc
so that the entire struct has a size that's a multiple of2
, the largest member size. That way, when you have an arrayX arr[10]
, all the elements ofarr
will be properly aligned individually.编译器在如何对齐数据方面拥有相当广泛的自由度。然而,实际上,基准的对齐不会超过其大小。也就是说,char 必须是字节对齐的,而 int 和 long 通常是四字节对齐的。
此外,结构体按照其成员最严格的对齐要求进行对齐。
因此,在您的示例中,最严格的内部对齐要求是 1 字节对齐,因此该结构是 1 字节对齐。这意味着它不需要填充。
The compiler is given fairly wide latitude about how its aligns data. As a practical matter, however, the alignment of a datum will not exceed its size. That is,
char
s must be byte-aligned, whileint
s andlong
s are often four-byte aligned.Additionally,
struct
s are aligned to the strictest alignment requirement of their members.So, in your example, the strictest internal alignment requirement is 1-byte aligned, so the struct is 1-byte aligned. This means that it requires no padding.