#progma pack ([n])表示内存对齐,目的是为了优化内存,减少内存碎片,使得内存按照一个固定的规则进行分配,让分配的内存总是n的倍数,避免随意分配内存大小。举个例子,我们在Visual C++中编写如下的类,
class X
{int a;
char b;
short c;
};
那么sizeof(X)等于多少?有人会说,很简单,sizeof(X)=4+1+2=7。有这种想法的朋友不妨到Visual C++中去试一试;认为sizeof(X)等于8的朋友,恭喜你们答对了,下面我们简单的分析一下原因。在Visual C++中有起始地址对齐的倍数规则,内容是各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为改变量的类型所占字节数的倍数。如下图所示,
图1 分配方式的对比
从图1中,我们可以看出,a和b的分配方式是相同的。根据起始地址对齐的倍数规则,如果c的偏移量为5,而c所占字节数为2,所以c的起始地址不能是5,而是6。
我们回过头来,说说progma pack吧。progma pack有两个规则:对齐长度规则和圆整规则。
1)对齐规则
结构、联合体或者类的数据成员的第一个放在偏移量为0的地方,以后每一个数据成员的对齐按照#progma pack制定的数值和这个数据成员的类型长度中取比较小的哪个值进行对齐。
例如#progma pack(4),使用上一例的Class X,那么sizeof(X)=8,根据对齐规则,按照指定的数值长度(4)和c的数据类型长度(2)中取较小者,那就是2,于是c按照2的倍数来对齐,也就是起始地址为6的位置。
2)圆整规则
在声明#progma pack(n)的情况下,整个数据类型的长度必须为n的倍数。例如我们编写如下的类Y,
class Y
{int a;
char b;
short c;
char d;
};
那么正常情况下,以及在对齐规则和圆整规则下内存分配方式如图2所示。
图2 对齐规则和圆整规则
经过简单地讲解,我想大家应该清楚#progma pack的作用了,那各位晚安了,好困呀……