c/c++:内存对齐详解

本文深入探讨了内存对齐的原因,解释了如何进行内存对齐,通过案例分析了不同对齐模数的影响,并详细讨论了32位和64位机内存对齐的差异。内容涵盖了内存对齐的基础知识,结构体的对齐规则,以及在不同操作系统上的实践应用。
摘要由CSDN通过智能技术生成

目录

一、内存对齐原因

二、如何内存对齐

三、内存对齐案例

3.1 对齐模数:8

3.2 对齐模数:4

3.3 实践说明

四、32位机和64位机内存对齐的区别


 

 

一、内存对齐原因

我们知道内存的最小单元是一个字节,当cpu从内存中读取数据的时候,是一个一个字节读取,所以内存对我们应该是入下图这样:

但是实际上cpu将内存当成多个块,每次从内存中读取一个块,这个块的大小可能是2、4、8、16等。

那么下面,我们来分析下非内存对齐和内存对齐的优缺点在哪?

内存对齐是操作系统为了提高访问内存的策略。操作系统在访问内存的时候,每次读取一定长度(这个长度是操作系统默认的对齐数,或者默认对齐数的整数倍)。如果没有对齐,为了访问一个变量可能产生二次访问。

 

  • 至此大家应该能够简单明白,为什么要简单内存对齐?
  1. 提高存取数据的速度。比如有的平台每次都是从偶地址处读取数据,对于一个int型的变量,若从偶地址单元处存放,则只需一个读取周期即可读取该变量;但是若从奇地址单元处存放,则需要2个读取周期读取该变量。
  2. 某些平台只能在特定的地址处访问特定类型的数据,否则抛出硬件异常给操作系统。

 

二、如何内存对齐

 

  • 对于标准数据类型,它的地址只要是它的长度的整数倍。
  • 对于非标准数据类型,比如结构体,要遵循一下对齐原则

1. 数组成员对齐规则。第一个数组成员应该放在offset为0的地方,以后每个数组成员应该放在offset:

min(当前成员的大小,#pargama pack(n))整数倍的地方开始,win#pargama pack(n)默认为8

比如int在32位机器为4字节,#pargama pack(2),那么从2的倍数地方开始存储)。

 

2. 结构体总的大小,也就是sizeof的结果,必须是min(结构体内部最大成员,#pargama pack(n))的整数倍,不足要补齐。

 

3. 结构体做为成员的对齐规则。如果一个结构体B里嵌套另一个结构体A,还是以最大成员类型的大小对齐:

min{ 结构体A的起点为A内部最大成员,#pargama pack(n) }

(struct B里存有struct A,A里有char,int,double等成员,那A应该从8的整数倍开始存储。),结构体A中的成员的对齐规则仍满足原则1、原则2。

手动设置对齐模数:

    1. #pragma pack(show)

显示当前packing alignment的字节数,以warning message的形式被显示。

    1. #pragma pack(push)

将当前指定的packing alignment数组进行压栈操作,这里的栈是the internal compiler stack,同事设置当前的packing alignment为n;如果n没有指定,则将当前的packing alignment数组压栈。

    1. #pragma pack(pop)

从internal compiler stack中删除最顶端的reaord; 如果没有指定n,则当前栈顶record即为新的packing alignement数值;如果指定了n,则n成为新的packing alignment值

    1. #pragma pack(n)

指定packing的数值,以字节为单位,,合法的数值分别是1,2,4,8,16。

Linux 默认#pragma pack(4) 
window 默认#pragma pack(8) 

 

内存对齐总结:

第一个属性开始  从0开始计算偏移量。
第二个和之后属性要放在  该属性的大小 与 对齐模数比  取小的值的 整数倍上。 
当所有属性都计算完毕后,整体做二次偏移,
将上面计算的结果 扩充到 这个结构体中最大数据类型 与对齐模数  比 取小的值 的整数倍。

 

 

三、内存对齐案例

所以案例均是 WIN 64位机上运行。

3.1 对齐模数:8

#pragma pack(8)

 

typedef struct _STUDENT{

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值