为什么一个由char,short和char(按此顺序)组成的结构,当用C ++编译并启用4字节打包时,会产生一个6字节的结构?

时间:2010-09-03 17:56:54

标签: c++ visual-c++ struct packing memory-alignment

我以为我理解了C / C ++如何处理结构成员对齐。但是我在Visual Studio 2008和2010中的特定安排中得到了奇怪的结果。

具体来说,我发现由char,short和char组成的结构被编译成6字节结构,即使启用了4或8字节打包。我不知道为什么会这样。我可以理解一个4字节的结构。我或许可以理解一个8字节的结构。但我认为当启用4字节打包时,不可能有6字节的结构。

演示此问题的程序是:

#include <iostream>
using namespace std;

#pragma pack (4)

struct Alignment
{
 char c1;
 short s;
 char c2;
};

#define REPORT_VAR_POSITION( structName, varName ) cout << "Member '" << #varName << "' sits at byte # " << offsetof( structName, varName ) << "." << endl;

int main(int argc, char* argv[])
{
 cout << "Sizeof struct Alignment is " << sizeof( Alignment ) << " bytes." << endl;
 REPORT_VAR_POSITION( Alignment, c1 );
 REPORT_VAR_POSITION( Alignment, s );
 REPORT_VAR_POSITION( Alignment, c2 );

 system( "pause" );

 return 0;
}

输出结果为:

Sizeof struct Alignment is 6 bytes.
Member 'c1' sits at byte # 0.
Member 's' sits at byte # 2.
Member 'c2' sits at byte # 4.
Press any key to continue . . .

有人可以解释为什么VC用一个额外的字节填充每个字符?

3 个答案:

答案 0 :(得分:16)

来自the MSDN documentation for #pragma pack(其中n是您设置的值):

  

成员的对齐将位于n的倍数或成员大小的倍数的边界上,以较小者为准。

sizeof(short)是两个字节,小于您设置的四个字节的打包值,因此short成员与两个字节的边界对齐。

最后charc2)后面加一个额外的字节,这样当Alignment个对象放在一个数组中时,short元素仍然正确在两字节边界上对齐。数组元素是连续的,它们之间不能有填充,因此必须在结构的末尾添加填充,以确保数组中的正确对齐。

答案 1 :(得分:4)

显然,你确实误解了它。在Visual Studio中,您不能通过使用struct packing设置增加任何类型的struct成员的对齐要求。你只能减少

如果你的结构由char(在1字节边界对齐)和short(在2字节边界对齐)对象组成,那么使用4和8字节打包设置将完全没有效果关于结构的布局或大小。结果与2字节打包完全相同。该结构的大小为6个字节。

在这种情况下唯一有效的打包设置是1字节打包设置,short的对齐要求从2减少到1并导致4字节大小结构。

答案 2 :(得分:-1)

使用此命令选项/ Zp [n]的Visual Studio的C编译器,其中结构打包在 n - 字节边界上,这是#pragma pack指令所在的位置,成员结构的对齐是在n的倍数的边界上。