先贴代码。范例是C++规范的,但是规则在C中也是通用的。

#include <iostream>

using namespace std;

struct testStructA {
 char aa[2];//2byte
 char bb[4];//4byte
 char cc[2];//2byte
 char dd[2];//2byte
 char ee[4];//4byte
} testObjA;

struct testStructB {
 char aa[2];//2byte
 int bb;//4byte
 char cc[2];//2byte
 char dd[2];//2byte
 int ee;//4byte
} testObjB;

int main(int argc, char **argv)
{
 int i;
 cout << "sizeof(int): " << sizeof(i) << "\n";
 char c;
 cout << "sizeof(char): " << sizeof(c) << "\n";

 cout << "sizeof(testObjA): " << sizeof(testObjA) << "\n";
 cout << "sizeof(testObjB): " << sizeof(testObjB) << "\n";

 return 0;
}

由C/C++规范可知:

  • char为1字节(byte)
  • int是4字节的。

testObjA 和 testObjB 看上去都是应该是14字节。但是实际的测试结果如下:

sizeof(int): 4
sizeof(char): 1
sizeof(testObjA): 14
sizeof(testObjB): 16

具体原因简单的说就是: C/C++ 在处理 struct 时有一个对齐的规则, struct 的内存宽度会被自动扩充到其包含的宽度最大的数据类型的宽度的整数倍。以 testObjB 为例就是会被扩充为 int 的宽度的整数倍,所以结果是16,而非14。

当然也可以临时性的修改 struct padding 规则,范例如下:

# include <iostream>

using namespace std;

# pragma pack(push)  /*push current alignment to stack*/
# pragma pack(1)     /*set alignment to 1 byte boundary*/

struct testStructC {
 char aa[2];//2byte
 int bb;//4byte
 char cc[2];//2byte
 char dd[2];//2byte
 int ee;//4byte
} testObjC;

# pragma pack(pop)   /*restore original alignment from stack*/

int main(int argc, char **argv)
{
 cout << "sizeof(testObjC): " << sizeof(testObjC) << "\n";

 return 0;
}

执行结果如下:

sizeof(testObjC): 14

参考