C++ 字节对齐

原因

  32 位处理器每次最多可以处理 32 位数据(也就是 CPU 的数据线是 32 位的,这里可以了解地址线和数据线),但是许多数据只需要 8位,16 位。比如文本处理常用的 ASCII 码,只需要 8 位,即使用 Unicode,也只要16位,所以 32 位处理器基本都具备处理更短位数数据的能力,也就是并非每次都一定要取 4 个字节的数据。实际上,计算机并非总是逐字节大小读写内存,而是以 2、4 或 8 的倍数的字节块来读写内存,有时也会只取一个字节。需要注意的是,只有位于 0x00、0x02、0x04、··· 的可以被 2 整除的位置上才会采取以 2 的倍数的字节块读写内存,只有位于 0x00、0x04、0x08、··· 位置上才会采取 4 的倍数的字节快读写内存,同理有 8 的倍数的字节块
  计算机在取数据的时候,偏向于取数据次数较少的取数方案,如一个 int 数据位于 0x02 上,那么计算机会先从 0x02-0x03 上取一个 short,然后从 0x04-0x05 上一个 short,两个拼接一起就是一个 int,需要取数 2 次。如果在 0x03 处,那么会先从 0x03 上取一个 char,然后从 0x04-0x05 上取一个 short,再从 0x06 上取一个 char,拼接成一个 int,需要取数 3 次。
  如果 int 正好位于 0x00 或 0x04 等位置,那么它只需要取数一次即可。因此,常常希望这些基本类型能够位于对齐的位置上,方便一次取出。

一些概念

自身对齐值

基本类型的自身对齐值

为指定平台上基本类型的长度。对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。

结构体或类的自身对齐值

其成员中自身对齐值最大的那个值。

指定对齐值

#pragma pack (value) 时的指定对齐值 value。

有效对齐值

自身对齐值和指定对齐值的较小值。

对齐原则

基本数据类型对齐原则

地址是长度的整数倍。

数组的对齐原则

按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。

联合的对齐原则

按其包含的长度最大的数据类型对齐。

结构体的对齐原则

每个成员都要对齐,编译器可能需要在结构体字段的分配中插入间隙,以保证每个结构元素都满足它的对齐要求。第一个数据变量的起始地址就是数据结构的起始地址结构体本身也要根据自身的有效对齐值圆整(就是结构体总长度需要是结构体有效对齐值的整数倍),此时可能需要在结构末尾填充一些空间,以满足结构体整体的对齐—-向结构体元素中最大的元素对齐。简而言之就是 (1)每个成员必须对齐,其地址可以被自身长度整除;(2)对于第一个元素,其地址应该可以被整个结构体的对齐字节数整除;(3)整个结构体是圆整的,总长度为最大长度数据成员的整数倍

实例

下面的结构体的 sizeof 是多少?

struct test
{
    char a;
    int b;
    short c;
    char d;
};

正确答案:12
如果首地址是 0x00,在内存中的图示可能是这样的:

a
bbbb
ccd
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值