C语言中的结构体内存对齐


一.何为内存对齐,内存对齐的作用

        我们现在使用的算机中内存空间都是按照字节(Byte)划分的,理论上说,似乎对任何类型的变量的访问可以从任意地址开始,但实际情况则是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型的数据按照一定的规则在内存空间上排列,而不是顺序的一个接一个地排放,这就是对齐

 

二.编译器内存字节对齐的原则

1.   数据类型的自身对齐值

       数据类型的自身对齐值:其在内存中所占的字节数,如在32位系统中,char为1字节,short为2字节,int、float、double、long为4字节。

2.  结构体或类的自身对齐值

       结构体或类的自身对齐值:其成员中自身对齐值最大的那个值。

3.  默认对齐值

       结构体或类的默认对齐值为其成员中自身对齐值最大的那个值。

4.  指定对齐值

      使用#pragma pack(value)时指定的值value。

5.  结构体和类的有效对齐值

       结构体和类的有效对齐值为:没有指定对齐值时为默认对齐值和自身对齐值的最小值;当指定了对齐值后为指定对齐值和自身对齐值的最小值。


三.如何修改编译器的默认对齐值

       在编码时,我们可以这样动态修改编译器的对齐值:

       1)修改默认对齐值,指定新的内存对齐值:#pragma pack(value)

       2)取消指定的内存对齐值,恢复默认对齐值:#pragma pack()


四.如何进行内存地址对齐

        对于一个结构体,不但需要对其每个成员变量进行内存地址对齐,还要对结构体本身进行对齐。具体规则是:在假设结构体起始地址为0x0000的情况下,要求各成员变量的起始地址必须是其相应有效对齐值整数倍,并要求结构体的大小也为该结构体有效对齐值的整数倍。

例1:[cpp] view plaincopy

  1. struct A  
  2. {  
  3.        int a;  
  4.        char b;  
  5.       short c;  
  6. };  

        则该结构体所占的内存字节数sizeof(struct A) = 8;

        具体分析如下:

        故该结构体及其成员变量的有效对齐值为编译器默认对齐值和其自身对齐值的最小值

                int a    的自身对齐值为4

                char b  的自身对齐值为1

                short c  的自身对齐值为2

                struct A 的自身对齐值为max(4,1,2) = 4

        编译器默认对齐值为各成员变量自身对齐值中的最大值,即为4。

                故  int a 的有效对齐值为min(4,4) = 4

                     char b 的有效对齐值为min(1,4) = 1

                     short c 的有效对齐值为min(2,4) = 2;

                     struct A 的有效对齐值为min(4,4) = 4

        假设结构体A从地址空间0x0000开始排放。由上面的计算可知,第一个成员变量int a的有效对齐值为4,所以其存放的地址为0x0000~0x0003,且其起始地址0x0000符合0x0000%4 = 0;第二个成员变量char b的有效对齐值为1,所以其存放地址为0x00004,且其起始地址0x0004符合0x0004%1 = 0;第三个成员变量short c 的有效对齐值为2,所以其存放地址应该为0x0006~0x0007,而其起始地址0x0006也符合0x0006%2 = 0;

        最后还要对整个结构体进行内存地址对齐:即要保证整个结构体的大小应该为其有效对齐值的整数倍,而该结构的有效对齐值为4,现在三个成员变量已经占据了0x0000~0x0007共8个字节的内存空间,而8%4 = 0也符合对齐要求,故整个结构体的大小应该为8.

 

例2[cpp] view plaincopy

  1. #pargma pack(8)  
  2. struct A  
  3. {  
  4.    short a; //有效对齐值为min(2,8) = 2  
  5.    long b;  //有效对齐值为min(4,8) = 4;  
  6. };  
  7.    
  8. struct B  
  9. {  
  10.    char c;      //有效对齐值为min(1,8) = 1  
  11.    struct B s;  //有效对齐值为min(4,8) = 4  
  12.    short e;     //有效对齐值为min(2,8) = 2  
  13. };  
  14. #pargma pack()  

        分别求出sizeof(struct A)和sizeof(struct B)的值。

        类似例4.1可分析:

        sizeof(struct A)= 8,sizeof(struct B)= 16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值