内存对齐问题分析

 

       个特定平台的编译器都有一个默对齐系数,gcc中是4VC中貌似是8。也可以通编译命令#pragma pack(n)来指定系数,其中n值经测试只能是124.

       对齐规则

       1构体的第一个数据成放在相位置0的地方,以后个数据成#pragma pack(n)n指定的数据成自身度中比小的那个对齐

       2、数据成完成对齐后,构体本身也要对齐,按照#pragma pack(n)n构体数据成中最度中小的对齐

验证境:gcc 4.4;sizeof(char)=1;sizeof(int)=4;sizeof(short)=2;sizeof(long)=4;sizeof(long long)=8):

       1、默情况(n=4

       struct st1 {

              char ch;//1<n,按1对齐,0%1=0,起始相位置=0;存放区[0]

              int num;//4=n,按4对齐 4%4=0,起始相位置=4;存放区[4,7]

              long lv;//4=n,4对齐8%4=0,起始相位置=8;存放区[8,11]

       };

       整个构体成员对齐后所占的区间为[0,8],12个字,接着构体本身对齐,成中最的是4n也等于4,所以构体本身按4对齐(即对齐系数)。

       整个构体的大小 = 比整个构体数据成所占的大或相等且和对齐系数求模0、与之距离最近的数。

       本例中,12%4=0,所以构体st112个字的空

       2#pragma pack(1)(n=1)

       struct st1 {

              char ch;//1=n,按1对齐0%1=0,起始相位置=0;存放区[0

              int num;//4>n,按n对齐 1%1=0,起始相位置=0;存放区[1,4]

              long lv;//4>n,n对齐5%1=0,起始相位置=5;存放区[5,8]

       };

       整个构体成员对齐后所占的区间为[0,8],9个字,接着构体本身对齐,成中最的是4n等于1,所以构体本身按1对齐(即对齐系数)。

       整个构体的大小 = 比整个构体数据成所占的大或相等且和对齐系数求模0、与之距离最近的数。

       本例中,9%1=0,所以构体st19个字的空

       3#pragma pack(2)(n=2)

       struct st1 {

              char ch;//1<n,按1对齐0%1=0,起始相位置=0;存放区[0

              int num;//4>n,按n对齐 2%2=0,起始相位置=2;存放区[2,5]

              long lv;//4>n,n对齐6%2=0,起始相位置=6;存放区[5,8]

       };

       整个构体成员对齐后所占的区间为[0,8],9个字,接着构体本身对齐,成中最的是4n等于2,所以构体本身按2对齐(即对齐系数)。

       整个构体的大小 = 比整个构体数据成所占的大或相等且和对齐系数求模0、与之距离最近的数。

       本例中,10%2=0,所以构体st110个字的空

       么说#pragma pack(n)n只能是124呢?

       比如3,如果n=3,编译候会警告“对齐边界必 2 小次方,而不是 3”,也就是是不起作用的,按默认对齐系数对齐

       再如8,会有什么结果?看下一例:

       4#pragma pack(8)(n=8)

       struct siz {

              char v1;

              long long v2;

              short v3;

              int v4;

       };

       如果8起作用,分析一下:

       struct siz {

              char v1;//1<n,按1对齐0%1=0,起始相位置=0;存放区[0

              long long v2;//8=n,按8对齐8%8=0,起始相位置=8;存放区[8,15

              short v3;//2<n,按2对齐16%2=0,起始相位置=16;存放区[16,17

              int v4;//4<n,按4对齐20%4=0,起始相位置=20;存放区[20,23

       };

       整个构体成员对齐后所占的区间为[0,23],24个字,接着构体本身对齐,成中最的是8n等于8,所以构体本身按8对齐(即对齐系数)。24%8=0,所以占24个字

       然而,很不幸,运行的果是20.

       接下来,用默对齐系数4来分析一下:

       struct siz {

              char v1;//1<4,按1对齐0%1=0,起始相位置=0;存放区[0

              long long v2;//8>4,按4对齐4%4=0,起始相位置=4;存放区[4,11

              short v3;//2<4,按2对齐12%2=0,起始相位置=12;存放区[12,13

              int v4;//4=4,按4对齐16%4=0,起始相位置=16;存放区[16,19

       };

       整个构体成员对齐后所占的区间为[0,19],20个字,接着构体本身对齐,成中最的是8n等于4,所以构体本身按4对齐(即对齐系数)。20%4=0,所以占20个字。与运行果一致。

       上分析,当n=8gcc仍然使用的是默对齐系数4.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值