梦回大唐之萧瑟流光内存对齐,是一个数据所能存放的内存地址的属性,它是一个无符号整数,且必须是2的幂。一个数据类型的内存对齐为
内存对齐是为了提高CPU读取数据的效率。并不是所有硬件平台都能够随意访问任意位置的内存,一些平台的CPU,若读取的数据是未对齐的,将拒绝访问或抛出硬件异常。
对于基本数据类型,其对其大小与其数据类型大小相等,例如int型数据的内存对齐值在默认情况下为4。
稍后将说明,由于第二条规则的存在,结构体本身的起始地址将不会影响以内部成员的相对位置。即将每个成员的对齐值作为其相对结构体起始地址的偏移量时,无论结构体本身的起始地址是多少,其内部成员的地址总是满足内存对齐规则(即其地址是其内存对齐值的整数倍)。
上述结构体本身的对齐值为8,即其成员对齐值得最大值,若我们强制令该结构体对对齐值小于8,则其成员的对齐值也将被强制不超过该值,因为只有当结构体本身的对齐值不小于其中成员的最大对齐值时,结构体中成员的相对位置才能保持固定。
例如,假设上述结构体对齐值为1,而其成员仍然按照自然对齐方式分布,则当该结构体起始地址为0x1时,其内存布局如下所示:
以此类推,当上述结构体按一字节对齐而不强制其成员按照一字节对齐时,结构体中成员的相对分布共有四种可能。结构体内部成员的相对位置分布随结构体本身的起始地址发生改变而发生变化显然不是我们所期望的。
而在保证了结构体本身的对齐值不小于其中成员的最大对齐值时,其成员的内存对齐总是可以满足的
但adr是一字节对齐的,adr有可能不在满足A内存对齐的位置上,这时用placement new可能会引起效率问题或出错,此时应该用std::aligned_storage构造内存块
std::align可以用来在一块内存中获取一个符合要求的地址,其原型如下:
从_Ptr所指的位置开始往后Space大小的内存块中,找一块大小为_Size,内存对齐大小为_Bound的内存,并将其地址放入_Ptr中,返回改地址。示例如下:
|