内存对齐规则总结

2023-05-16

由于某些硬件平台不能任意访问地址数据,只能在某些地址处取某些特定类型的数据;并且处理器访问未对齐的内存时,需要多次读取并对多余数据进行剔除,相较于对齐内存访问,耗费了更多的时间,降低了数据访问效率,因此需要内存对齐。

一、内存字节对齐的规则

1.数据类型自然边界对齐

char型数据自身对齐值为1字节,short型数据为2字节,int/float型为4字节,double型为8字节,long型数据为4字节(32位编译器)或8字节(64位编译器),void*型数据为4字节(32位编译器)或8字节(64位编译器)。

2.结构体、类的自身对齐

为结构体分配内存时,分配的内存大小至少是各个字段的长度和。通常,分配的结构体的长度会大于结构体各个字段的长度和,因为结构体需要对齐,即结构体各字段之间需要填充。

缺省情况下,编译器为结构体的每个成员按其自然边界对齐方式分配空间,并按照每个成员被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构体的地址相同。结构体整体的默认字节对齐值是结构体中所有成员中对齐参数最大值,结构体长度的计算必须取所用过的所有对齐参数的整数倍。

结构体中每个成员的首地址是成员自身自然边界对齐值的整数倍,如果成员自身大小大于指定对齐字节,以指定对齐字节整数倍为基准对齐;

结构体整体对齐方式取决于结构体中所有成员的自然边界对齐值最大值的整数倍,如果最大成员大小超过指定对齐字节,以指定对齐字节整数倍为基准对齐(也叫补齐,目的是多个结构体连续存储时也满足对齐要求)。

3.编译器指定对齐

内存字节对齐是GCC编译器对C语言进行的扩展。在缺省情况下,C编译器为每一个变量或是数据单元按其自然边界对齐条件分配空间。

(1)GCC编译器两种内存对齐的方法

属性设置方式(推荐)

__attribute__ ((aligned(n))); //让所作用的结构体或者类或者联合或者一个类型的变量(对象)分配地址空间时的地址在编译过程中按n字节对齐
__attribute__ ((packed)); //取消结构在编译过程中的优化对齐

如果__attribute__((aligned(n)))作用于一个类型,那么该类型的变量在分配地址空间时,其存放的地址一定按照n字节对齐(n必须是2的幂次方);如果类型中的成员的自然边界对齐值大于n,则按照机器字长(32位或者64位)对齐。类型占用的空间,即大小,需要是n的整数倍,以保证在申请连续存储空间的时候,每一个元素的地址也是按照n字节对齐。

32位处理器指定4字节对齐方式实例如下:

struct test{
    char a[18];
    double b;
    char c;
    int d;
    short e;
}__attribute__((aligned(4)));//实际有效指定对齐值为4字节(机器字长)

sizeof(struct test);//40字节

第一个成员(char a[18]):假设放在内存开始地址为0的位置,占用内存地址范围为0~18。

第二个成员(double b):double类型占8字节,大于指定对齐字节(4字节),因此以4字节对齐为基准。由于第一个成员结束地址为18,不是4的整数倍,需要再加2个字节从地址20开始。

第三个成员(char c):char类型占1字节,可以直接从第二个成员结束地址28开始。

第四个成员(int d):int类型占4字节,地址29不是4的整数倍,需要加3个字节,从地址32开始。

第五个成员(short e):short类型占2字节,地址36刚好是2的整数倍,可以直接放在当前地址。

最后是对整个结构体补齐,该结构体中最大字节为8字节(double类型),大于指定对齐字节,所以还是以4字节补齐为基准。整个结构体结束地址为38,地址38不是4的整数倍,需要额外加2个字节填充,即整个结构体的大小为40字节。具体对齐结构如下图所示。

伪指令方式(最多只支持8字节对齐,不建议使用)

#pragma pack(n) //n取值可以为1、2、4、8,在编译过程中按照n个字节对齐
#pragma pack() //取消指定对齐,按照编译器的优化对齐方式对齐

32位处理器指定4字节对齐方式实例如下:

#pragma pack(4)
struct test{
    char a;
    int b;
    short c;
    char *p;
    double d;
};
#pragma pack()

sizeof(struct test);//24字节

(2)其他编译器内存对齐方式

#if defined   (__CC_ARM) /*!< ARM Compiler */ //MDK
    __align(4) uint16_t data[40];
    //存储类修饰符,只修饰最高级类型对象,不能用于结构或者函数对象
    //__packed是1字节对齐,不使用__packed的话系统以默认方式对齐

#elif defined ( __ICCARM__ ) /*!< IAR Compiler */ 
    #pragma data_alignment=4 
    uint16_t data[40];

#elif defined (__GNUC__) /*!< GNU Compiler */ 
    __attribute__ ((aligned (4))) uint16_t data[40]; 

#elif defined  (__TASKING__) /*!< TASKING Compiler */ 
    __align(4) uint16_t data[40];

#endif /* __CC_ARM */

二、检查内存地址是否对齐(4字节为例)

4字节对齐的地址是4(100b)字节的整数倍,也就是说地址的二进制表示形式以00结尾,因此可以通过以下方式对4字节对齐地址进行测试:

if((address & 0x3) == 0)
{
    //The address is 4-byte aligned here
}

if(address & 0x3)
{
    //The address is not 4-byte aligned here
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内存对齐规则总结 的相关文章

  • srs 直播连麦环境搭建

    一 简介 二 修改conf rtc conf 三 两个客户端加入房间 四 合流 4 1分别拉流尝试 4 2合流推流 4 3拉取合流 一 简介 直播连麦是指在one2one或one2many进行音视频通话 xff0c 此时把他们的音视频流合在
  • DM-VIO安装与运行各类数据集

    1 论文地址 xff1a https vision in tum de media research vslam dm vio dm vio pdf https vision in tum de media research vslam d
  • sklearn风格的keras接口KerasClassifier、KerasRegressor

    span class token keyword from span tensorflow span class token punctuation span keras span class token punctuation span
  • python与java通信——使用socket模块

    前几天遇到个问题需要用python和java通信 xff0c 网上这种帖子很多 xff0c 比如runtime方法 xff0c py4j方法等 但是runtime方法似乎只能向python传参 xff0c 不能接受python传回 xff1
  • 简单移动平均SMA和指数移动平均EMA

    一 简单移动平均SMA 最近有一个平滑的需求 xff1a 设置平滑期数h xff08 奇数 xff09 xff0c 每期点平滑方法是 xff1a 取该期前后共m期 xff08 含本期 xff09 点的平均值 如果前或后没有足够的点则不用平滑
  • postman基础教程

    目录 一 postman安装说明 1 下载与安装 2 界面导航说明 3 发送第一个请求 二 postman基础功能 1 常见类型的接口请求 1 1 查询参数的接口请求 1 2 表单类型的接口请求 1 3 上传文件的表单请求 1 4 json
  • pandas使用分位数筛选满足条件的行

    分位数计算原理参见 python pandas 分位数 下面直接使用pandas的quantile方法 1 给个例子 span class token keyword import span pandas span class token
  • pandas str.endswith筛选结尾字符串为一个范围内的行

    span class token keyword import span numpy span class token keyword as span np span class token keyword import span pand
  • 聚类集成方法python实现(基于相似度、基于重标记法)

    一 写此篇的背景 有个同学给我两篇论文 基于聚类集成的特征选择方法研究 李玥 基于基聚类器对齐的聚类集成方法研究 杨康 xff0c 基于相似度的方法跟他讲了一遍他自己复现好了 xff0c 但是他觉得他的数据集有几万条 xff0c 时间和空间
  • pandas 如何获得每类A的月末数据B

    一 描述问题 如何取到下面这个dataframe中 xff0c 每一类Code对应的月末数据 df span class token operator 61 span pd span class token punctuation span
  • pandas groupby分组后对每个组进行fillna填值

    一 初始数据如下 xff0c 希望分组后 xff0c 组间数据互不干扰的填充 span class token keyword import span pandas span class token keyword as span pd s
  • VS2022配置Games101作业环境

    一 首先配置opencv4 43 contrib 1 opencv源码下载 访问github上的opencv主页 首先点进第一个opencv 我这里默认就是4 x xff0c 点开可以知道分支为4 x 还需要点Tags 我这里使用的是4 5
  • Games101 VS2022 C++ auto推断不出变量类型

    在写Games101 Homework2的时候 xff0c 下面这句的 auto推断不出3个变量的类型 span class token comment If so use the following code to get the int
  • 密度聚类:OPTICS算法详解

    很多人不理解OPTICS算法绘出的图该怎么理解 为什么波谷就算一类 xff0c 有个波峰又算另一类了 xff0c 本篇在第三部分的第2 3节详细讲这个是什么判别分类的 本篇会添加一些个人思考过程 xff0c 可能有不严谨的地方 xff0c
  • 密度聚类:OPTICS算法简单易懂版

    前几天写了一篇详解版 xff0c 感觉可能太详细了阅读量不高 xff0c 所以修改精简成这篇 很多人不理解OPTICS算法绘出的图该怎么理解 为什么波谷就算一类 xff0c 有个波峰又算另一类了 xff0c 本篇在第三部分的第2 3节详细讲
  • 跟着LearnOpenGL文档做的纹理显示不出来,但也不报错

    跟着LearnOpenGL文档入门章的纹理一节 xff0c 把源代码复制下载都运行不了 xff0c 有这么3条要注意的点 一 下载完stb image h xff0c 引用时要加上 define STB IMAGE IMPLEMENTATI
  • 【C++】一文搞懂C++中的std::是什么

    1 C 43 43 中的std 是什么 xff1f std 是个名称空间标示符 xff0c C 43 43 标准库中的函数或者对象都是在命名空间std中定义的 xff0c 所以我们要使用标准函数库中的函数或对象都要使用std来限定 标准库在
  • 详解GMM高斯混合模型EM模型

    一般讲到GMM就会讲到EM 我不过多的介绍EM算法 这里只是举一些例子来看看真实的GMM怎么用EM算的 一 GMM的作用 记住GMM的作用 xff0c 就是聚类 xff01 二 GMM有hard和soft两种 hard GMM和soft G
  • MiniAlphaGo黑白棋 蒙特卡洛搜索

    做个笔记 一 蒙特卡洛在黑白棋的应用 输入 xff1a 棋盘 x1d44f x1d45c x1d44e x1d45f x1d451 当前执子方 x1d450 x1d45c x1d459 x1d45c x1d45f 搜索时间 x1d461 x
  • 基于LLVM的C编译器--lcc——以CLion用SSH连接WSL Ubuntu22.04为例

    Windows 10 22H2CLion 2022 3 1Ubuntu 20 04 xff08 Microsoft Store内的WSL发行版 xff09 一 下载WSL xff0c 换源 xff0c 切换到WSL2 1 1 保证windo

随机推荐

  • Windows有CUDA但是没有nvcc命令

    明明有CUDA xff0c 但是cmd中输入nvcc V无效 但是如果打开anaconda prompt xff0c 输入nvcc V就有效 这可能是因为直接用的pytorch官网命令conda下载安装的 xff0c 然后又没有把anaco
  • win下配置pytorch3d

    一 配置好的环境 xff1a py 3 9 43 pytorch 1 8 0 43 cuda 11 1 cudnn 8 0 43 pytorch3d 0 6 0 43 CUB 1 11 0 你可能觉得pytorch3d 0 6 0版本有点低
  • 【pytorch3d】running build_ext error: [WinError 2] 系统找不到指定的文件

    在win10上安装pytorch3d时 xff0c 遇到如下错误 xff1a running build ext error span class token punctuation span WinError span class tok
  • windows下安装jax

    一 首先下载jaxlib 需要去这个非官方网站去找到适合自己的版本 xff0c 下载到本地 然后使用对应的虚拟环境pip install 该文件名即可 二 然后下载对应的jax 一行命令即可 pip span class token fun
  • STM32 HAL库串口收发数据

    STM32 HAL库串口收发数据 许多传感器的使用方法是 xff1a 单片机给传感器发送一帧数据 xff0c 然后传感器返回单片机一帧有用数据 xff0c 所以串口的收发功能十分重要 STM32cubeMX的配置 时钟和下载方式就不讲了 串
  • W7,显卡型号nvidia geforce 840M,安装tensorflow-gpu

    记录一下 xff0c 以防忘记 1 首先我拿驱动精灵把显卡驱动升到最新 xff0c 然后在NVIDIA 控制面板里查看支持CUDA9 1 xff0c 但是我下载了CUDA9 0 43 cudnn7 0 xff0c 先不用安装 注意 xff0
  • IP和MAC的作用

    IP地址的作用以及MAC地址的作用 MAC地址是一个硬件地址 xff0c 用来定义网络设备的位置 xff0c 主要是数据链路层负责 IP地址是IP协议提供的统一的地址格式 xff0c 为互联网上的每一个网络和每一台主机分配一个逻辑地址 xf
  • SPI简介

    SPI全称是Serial Perripheral Interface xff0c 也就是串行外围设备接口 SPI是Motorola公司推出的一种同步串行接口技术 xff0c 是一种高速 xff0c 全双工的同步通信总线 SPI时钟频率相比I
  • npm 错误码 EMISSINGARG

    EMISSINGARG Error npm ERR node v6 6 0 npm ERR npm v3 10 3 npm ERR code EMISSINGARG npm ERR typeerror Error Missing requi
  • axios.response返回数据格式

    axios response接口中存储的是如下内容 xff1a 96 data 96 是服务器的提供的回复 xff08 相对于请求 xff09 data 96 status 96 是服务器返回的http状态码 status 200 96 s
  • flask实现下载文件、前后端

    采用前后端分离的过程中 xff0c 前端只能下载静态文件中的文件或者url下载文件 但是 xff0c 一般情况下文件要么是远程或者存在于其他文件夹 这种情况就需要采用后端预先下载文件 xff0c 传递给前端 flask有几种文件传输方式 x
  • python+flask 简单并发,使用gevent库

    pip install geventfrom gevent wsgi import WSGIServer 关键这个WSGIServer 127 0 0 1 5000 app serve forever
  • java中Array.remove()方法,源码中不对负索引进行检查

    public E remove int index 检查remove源码是 xff0c 发现 其中对index 的检查仅限于上溢出检查 没有显示的对下溢出进行检查 xff1f rangeCheck index modCount 43 43
  • java- 类名.this.成员 和 this.成员 的区别

    this 成员 xff1a this用于本类中 xff0c 自身的引用 xff0c 调用自身对象属性 类名 this 成员 用于内部内 xff0c 调用外部类的成员 用 外部类 this 表示外部类的引用 xff0c 用以 和 自身类进行区
  • java异常 Exception in thread “main“ java.lang.IllegalArgumentException: Comparison method violates its

    Exception in thread 34 main 34 java lang IllegalArgumentException Comparison method violates its general contract at jav
  • 速查matplotlib-python中画图曲线的形状和颜色

    速查matplotlib python中画图曲线的形状和颜色 在属性值先写颜色 xff0c 后写形状如 xff1a r 红色曲线 b 蓝色短横线 等 字符描述 39 39 实线样式 39 39 短横线样式 39 39 点划线样式 39 39
  • python-pyplot直方图,标注直方图数据

    话不多说 由于自己一直忘记直方图的一些细节 xff0c 经常不用 xff0c 老得百度 xff0c 干脆自己记下来好了 这是直方图的写法与标注直方图的数据写法 如下 from matplotlib import pyplot as plt
  • 从零开始学JetsonTX2----can bus开发

    step by step implementation 搞硬件开发 xff0c 先把技术手册搞到手 这个网页把几乎Jetson tx2的开发资料都汇总了一下 找教程开始配置can所需要系统环境 NIVIDA社区的教程 xff1a https
  • CAN总线详解

    目录 CAN 协议简介1 xff0c 何为CAN 1 1 CAN的应用实例1 2 总线拓扑图1 3 CAN的特点 2 xff0c CAN 电气属性3 xff0c CAN 协议3 1 数据帧3 2 遥控帧3 3 错误帧3 4 过载帧3 5 间
  • 内存对齐规则总结

    由于某些硬件平台不能任意访问地址数据 xff0c 只能在某些地址处取某些特定类型的数据 xff1b 并且处理器访问未对齐的内存时 xff0c 需要多次读取并对多余数据进行剔除 xff0c 相较于对齐内存访问 xff0c 耗费了更多的时间 x