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

目录

一、内存对齐原因

二、如何内存对齐

三、内存对齐案例

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数组压栈。

    • 4
      点赞
    • 2
      收藏
      觉得还不错? 一键收藏
    • 2
      评论
    很抱歉,我之前的回答有误。在VSCode,没有名为"C/C++: Edit Configurations"的具体插件或设置。忽略我之前的错误信息。 对于C/C++开发环境的配置,你可以按照以下步骤进行: 1. 确保已安装C/C++插件:在VSCode,点击左侧导航栏的扩展按钮(或按下`Ctrl+Shift+X`快捷键)打开扩展面板。在搜索框输入"C/C++",找到并安装"Microsoft C/C++"插件。 2. 配置编译器和头文件路径:在VSCode,点击左侧导航栏的文件夹图标打开文件资源管理器。打开你的C/C++项目文件夹,并在该文件夹创建一个名为`.vscode`的文件夹(如果还没有)。在`.vscode`文件夹创建一个名为`c_cpp_properties.json`的文件,并在其添加以下内容: ```json { "configurations": [ { "name": "Win32", "includePath": [ "${workspaceFolder}/**" ], "defines": [], "compilerPath": "YOUR_COMPILER_PATH", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "gcc-x64" } ], "version": 4 } ``` 确保将`YOUR_COMPILER_PATH`替换为你实际使用的编译器路径。 3. 配置任务(可选):在VSCode,按下`Ctrl+Shift+P`快捷键,打开命令面板。输入"Tasks: Configure Default Build Task"并选择该选项。然后选择你使用的编译器,例如"g++"或"clang++"。这将在项目根目录下创建一个名为`tasks.json`的文件,并在其定义默认的构建任务。 以上步骤可以帮助你配置C/C++开发环境并使用VSCode进行编码和调试。祝你编程愉快!

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

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

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值