现在的位置: 首页 > 综合 > 正文

对数据对齐的探索

2012年02月20日 ⁄ 综合 ⁄ 共 1234字 ⁄ 字号 评论关闭

有如下的两个结构体:

struct A                                       struct B         
{                                                {
    int a;                                           int a;
  unsigned __int64 b;                  short c;   
  short c;                                      unsigned __int64 b;
};                                               };  

那么sizeof(A) sizeof(B)一样吗?让我在编译器里试一下,啊?怎么不一样?两个结构体明明相同,只是第二和第三个成员变量的位置颠倒了结果却大相径庭。到底是因为什么呢?

答案是编译器的数据对齐方式在作怪。以vc6.0为例,默认情况下的对其方式是8位。所以struct A的大小为24struct B的大小为16,下面就具体分析一下数据空间占用情况。

Struct A中的,编译器首先检测所有的成员变量中的size最大值。很显然unsigned __int64最大,sizeof(unsigned __int64)8,然后第一个变量aint型只占4个字节,但是为了对齐其被补上了四个字节,接着变量b 变量a有效位置之后被放置,但是目前只有4个空闲的字节,根本放不下变量b,于是编译器就再申请了8字节的空间大小,将变量b放在4个空闲字节之后,也就是说变量b的起始位置在第九个字节。由于变量b需要8个字节所以没有留给变量c任何的剩余空间,于是变量c再次申请8个字节的空间用于存储自己,当然它本可以只申请2字节的空前就行了,但是为了对齐他只能申请8字节。那么最后我们就可以看到如下图所示的数据存储结构:

0

8

15

23

a

多申请的空间

b

c

 

多申请的空间

                               

Struct B中的, 编译器前几步的处理也和struct A的一样,直到该处理变量c 时,编译器依然要先看看为变量a分配的空间是否还有多余并且多余的空间是否足以容纳下变量c,由于变量c只需要两个字节,而a却有4个字节的剩余空间,所以变量c就很轻松的被放置在a之后的4个字节内而不需要再申请空间。变量b依然申请8字节的空间并跟随在变量a空余空间之后。最后我们就可以看到如下图所示的数据存储结构:    

0

1

2

3

4

5

6

7

8

15

a

 

 

 

c

 

多申请的空间

b

 

                                         

通过以上的分析我们明白了结构体内部(也可以引伸到类的内部!)成员变量的声明顺序并不是随意的,尤其是在内存需求特别紧张的开发环境中。

 

抱歉!评论已关闭.