#pragma pack()

一般的pack对齐格式分别是1,2,4,8,16.

默认的对齐格式,也就是:#pragma pack()

情况下,会在结构体中挑选占用字节最多的类型,例如double 占用8个字节,例子:

#pragma pack()

struct A

{

   char c;    char c1;

   int a;

   double d;

};

上面的结构体长度是16.为什么是16,而不是char 8 int 8 double 8

实际上,当我们采用默认的对齐,决定存储的长度是8个字节,所以每8个字节为一组,存放数据,但是可能像上面的情况是一个字节的字符,占用了1个字节的存储空间,编译器尝试利用剩余的7个空,避免读取寄存器数值 的时候,从奇数的位置开始读取数据。所以跳过了一个1个字节。发现下一个元素刚好可以填充从第3个字节开始的位置,所以填充。现在位置移动到了第5个字节,还剩下4个字节,这一组就分配完毕了,此时遇到了一个整型,刚刚好。

如果指定了字节对齐的个数,情况就会不一样:

#pragma pack(1)

struct A

{

   char c;    char c1;

   int a;

   double d;

};

变成了14个字节。


#pragma pack(push)和#pragma pack(pop) 

在使用#pragma pack()的过程中,通常会通过上面两个宏定义将#pragma pack()和定义结构体包含进来,例如

#pragma pack(push)

#pragma pack(1)
struct A
{
    char c;    
    char c1;
    int a;
    double d;
};

#pragma pack(pop)

 否则会导致其他库受到影响,例如boost::asio添加到项目,编译通过,运行会出现无法连接到服务器端口的问题,相关的问题可以查看HTTP-SIMPLE-SERVER库的使用


总结

如果没有指定字节对齐,挑选字节长度最长的类型作为对齐的字节数。然后分配对齐字节数的空间,尝试将结构体的成员,往里面塞,注意存在的开始地址必须是偶数。