如何判断一个结构体的实际占用空间

背景

cpu读取内存是以2的整数次幂为单位读取(一次读取一块内存,如一次读入4个字节),如果不进行对齐,那么本来只需要一次进行的访问,可能需要好几次才能完成,并且还要进行额外的merger或者数据分离。

方法

  • 先确定实际对齐单位,其由以下三个因素决定
  1. 结构体最大成员(基本数据类型变量)

  2. 预编译指令#pragma pack(n)手动设置 n–只能填1、2、4、8、16

  3. CPU周期

    • WIN vs qt 默认8字节对齐
    • Linux 32位 默认4字节对齐,64位默认8字节对齐

    上面三者取最小的,就是实际对齐单位(这里的“实际对齐单位”是我为了方便区分随便取的概念)

  • 除结构体的第一个成员外,其他所有的成员的地址相对于结构体地址(即它首个成员的地址)的偏移量必须为实际对齐单位或自身大小的整数倍(取两者中小的那个)

  • 结构体的整体大小必须为实际对齐单位的整数倍。

  • 嵌套结构体的实际对齐单位是自己内部成员的对齐数中的最大对齐数。

例子

x86_64环境

设结构体如下定义:

struct A
{
    int a;
    char b;
    short c;
};
struct B
{
    char b;
    int a;
    short c;
};

对于结构体A:

  • 实际对齐单位为4(最大成员变量)
  • a的偏移量为0
  • b的偏移量为4
  • c的偏移量为6
0 --- a
1 --- a
2 --- a
3 --- a
4 --- b
5 --- buff
6 --- c
7 --- c

总大小为8


对于结构体B:

  • 实际对齐单位为4
0 --- b
1 --- buff
2 --- buff
3 --- buff
4 --- a
5 --- a
6 --- a
7 --- a
8 --- c
9 --- c
10 -- buff
11 -- buff

总大小为12

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值