内存对齐原则

1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小的最宽基本类型(只要该成员有子成员,比如说是数组,结构体等)和指定对齐值(有宏 #pragma pack(N) 指定的值这里面的N一定是2的幂次方。如1,2,4,8,16等,如果没有通过宏那么在32位Linux主机上默认指定对齐值为4,64位的默认对齐值为8,AMR CPU默认指定对齐值为8)两者中的最小值的整数倍开始(比如int在32位机为4字节, 则要从4的整数倍地址开始存储),即min{自身对齐值,指定对齐值}的整数倍,基本类型不包括struct/class/uinon。

2).结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部"最宽基本类型成员"的整数倍地址开始存储(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储)。

3).收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的"最宽基本类型成员"的整数倍和指定对齐值中最小值的整数倍,即min{所有成员中自身对齐值最大的, 指定对齐值}的整数倍,不足的要补齐(基本类型不包括struct/class/uinon)。

4).sizeof(union),以结构里面size最大元素为union的size,因为在某一时刻,union只有一个成员真正存储于该地址,有关union的内存对齐具体内容在我的另外一篇博文提到(https://blog.csdn.net/shuaifeng_/article/details/118703146)。
eg:
64位Linux情况下:
#pragma pack(2)
typedef struct a{
  char b;
  int  c;
  short b;
}
结果为:8。让我们分析一下为什么结果为8。

#pragma pack(2):设置结构体的边界对齐为2个字节。

a是char类型,占1个字节。第一个数据成员,放在结构体变量偏移量为0的地址处。

c是int类型,占4个字节,我们根据结构体对齐规则可知,c的对齐值从min{4,2}的整数倍开始,因为此处指定对齐值为#pragma pack(2)中的2。对齐到2的整数倍地址,即地址偏移量为2处。在内存中存放的位置为2,3,4,5。

b是short类型,占2个字节,我们根据结构体对齐规则可知,b的对齐值从min{2,2}的整数倍开始,对齐到2的整数倍地址,即地址偏移量为6处。在内存中存放的位置为6,7。

结构体总对齐字节大小为min{4, 2}=2的整数倍。此时内存中共占8个字节,正好是2的整数倍,所以sizeof(st_struct1)=8。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值