background image

char dda;      //偏移量为 0,满足对齐方式,dda 占用 1

 

个字节;

double dda1;//下一个可用的地址的偏移量为 1,不是 sizeof(double)=8 
                    //的倍数,需要补足 7 个字节才能使偏移量变为 8

 

(满足对齐

                   //方式),因此 VC 自动填充 7 个字节,dda1 存放在偏移量为 8 
                  //的地址上,它占用 8

 

个字节。

int type

    

//下一个可用的地址的偏移量为 16,是 sizeof(int)=4

 

的倍

           //数,满足 int 的对齐方式,所以不需要 VC 自动填充,type

 

           //放在偏移量为 16 的地址上,它占用 4

 

个字节。

};//所有成员变量都分配了空间,空间总的大小为 1+7+8+4=20

 

,不是结构

   //的节边界数(即结构中占用最大空间的类型所占用的字节数 sizeof 
   //(double)=8)的倍数,所以需要填充 4

 

个字节,以满足结构的大小为

   //sizeof(double)=8

 

的倍数。

所以该结构总的大小为:sizeof(MyStruc)为 1+7+8+4+4=24。其中总的有 7+4=11
个字节是 VC

 

自动填充的,没有放任何有意义的东西。

VC 对结构的存储的特殊处理确实提高 CPU 存储变量的速度,但是有时候也
带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的

 

对齐方式。
VC 中提供了#pragma pack(n)来设定变量以 n 字节对齐方式。n 字节对齐就是说
变量存放的起始地址的偏移量有两种情况:第一、如果 n 大于等于该变量所占
用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果 n 小于该变量
的类型所占用的字节数,那么偏移量为 n 的倍数,不用满足默认的对齐方式。
结构的总大小也有个约束条件,分下面两种情况:如果 n 大于所有成员变量
类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的

 

空间数的倍数;
否则必须为 n

 

的倍数。下面举例说明其用法。

#pragma pack(push) //

 

保存对齐状态

#pragma pack(4)//设定为 4

 

字节对齐

struct test 

char m1; 
double m4; 
int m3; 
}; 
#pragma pack(pop)//

 

恢复对齐状态

以上结构的大小为 16,下面分析其存储情况,首先为 m1 分配空间,其偏移量
为 0,满足我们自己设定的对齐方式(4 字节对齐),m1 占用 1 个字节。接着

 

开始为 m4 分配空间,这时其偏移量为 1,需要补足 3 个字节,这样使偏移量
满足为 n=4 的倍数(因为 sizeof(double)大于 n),m4 占用 8 个字节。接着为 m3
分配空间,这时其偏移量为 12,满足为 4 的倍数,m3 占用 4 个字节。这时已
经为所有成员变量分配了空间,共分配了 16 个字节,满足为 n 的倍数。如果把
上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为
24。(请读者自己分析)

三、再看下面这个例子