C语言之内存对齐

一、为什么要内存对齐

Arm对内存的访问支持字(4byte)、半字(2byte)、字节(1byte)的直接访问,但是呢他们是有一定的要求的:

  • 存取字时要求地址按字对齐,也就是地址要是4的整数倍,如0x0000、0x0004、0x0008(该地址只是举例,mcu的地址分配请参考具体手册的地址映射图)

  • 存取半字是要求地址按半字对齐,也就是地址是2的倍数,这样假如通过0x0001、0x0003这样非2倍数的地址来读取一个半字就会进入硬件中断错误

  • 存取字节简单,只要地址不超范围就可以

二、内存对齐的意义是什么? 

        提高内存访问速度

        尽管内存是以字节为单位,但是大部分处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存,我们将上述这些存取单位称为内存存取粒度.

现在考虑4字节存取粒度的处理器取int类型变量(32位系统),该处理器只能从地址为4的倍数的内存开始读取数据。

假如没有内存对齐机制,数据可以任意存放,现在一个int变量存放在从地址1开始的联系四个字节地址中,该处理器去取数据时,要先从0地址开始读取第一个4字节块,剔除不想要的字节(0地址),然后从地址4开始读取下一个4字节块,同样剔除不要的数据(5,6,7地址),最后留下的两块数据合并放入寄存器.这需要做很多工作。但如果有内存对齐机制,那么直接从0地址读出4个字节,就可以得到数据内容。

三、内存对齐规则

  • 数据成员对齐:成员根据其自身大小,从自身大小的整数倍内存地址(以第一个元素存储在0位置为参考)开始存储;
  • 结构体成员对齐:首个成员从偏移量 0 开始存储。后续成员偏移地址为 min(自身对齐值, 编译器指定对齐值) 的整数倍。
  • 结构体总大小对齐:结构体总大小需为 最大成员对齐值 的整数倍,不足时末尾填充字节。

四、如何实现内存对齐

#pragma pack(n)   作用:强制指定对齐值为 n

#pragma pack(1)      // 设置为1字节对齐(无填充)
struct Data {char a;          // 1字节 int b;           // 4字节(紧密排列)
};                   // sizeof = 5 
#pragma pack()       // 恢复默认对齐 

__attribute__((aligned(n)))    作用:指定结构体/变量的最小对齐值。

struct __attribute__((aligned(8))) AlignStruct {char c;          // 结构体整体按8字节对齐 int i;
};                   // sizeof = 8(而非5)

注意:主要方式跨平台,由于不同平台编译器默认的对齐大小不同,导致硬件中断问题,例如Windows默认8字节对齐,Linux默认4字节

五、字节对齐应用场景

比如别人传输一大段数据过来,然后它默认一字节对齐,此时数据接收就会紊乱,这时候就必须强制对齐

typedef union  __attribute__((aligned(16)))  DataPacket {  uint16_t raw_bytes[10];     // 原始字节访问接口 struct SensorData {  uint32_t temperature; // 温度值 (4字节)uint8_t status;      // 状态标志 (1字节)uint16_t id;         // 设备ID (2字节)uint8_t status2;      // 状态标志 (1字节)uint8_t data[3];uint8_t status3;      // 状态标志 (1字节)} sensor;
} DataPacket;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/910198.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/910198.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 基础语法 -----函数

一、函数 1、函数是什么 编程中的函数和数学中的函数有一定的相似之处。 数学上的函数,比如 y sin x,x 取不同的值,y 就会得到不同的结果。 编程中的函数是一段可以被重复使用的代码片段。 (1)求数列的和&#x…

Windows/Linux系统 Ollama部署deepseek 大模型

Ollama 是一个开源工具,专门用于在本地计算机上运行和操作大型语言模型(LLM) 官方下载网站(https://ollama.ai/) Windows系统安装方法 建议命令行安装(默认安装会直接安装到C盘) OllamaSetu…

用Tensorflow进行线性回归和逻辑回归(一)

这一章告诉你如何用TensorFlow构建简单的机器学习系统。第一部分回顾构建机器学习系统的基础特别是讲函数,连续性,可微性。接着我们介绍损失函数,然后讨论机器学习归根于找到复杂的损失函数最小化的点的能力。我们然后讲梯度下降,…

java/.net跨平台UI浏览器SDK,浏览器控件开发包分析

在 Linux 系统中,虽然没有完全等同于安卓 WebView 的内置浏览器 SDK,但存在多种基于开源浏览器引擎的解决方案,支持通过 Java 代码控制网页加载和执行 JavaScript。以下是具体实现方案和技术细节: 一、核心技术方案对比 方案名称…

Taro 状态管理全面指南:从本地状态到全局方案

在跨端应用开发中,状态管理是构建可维护、可扩展应用的核心环节。作为京东凹凸实验室推出的多端统一开发框架,Taro 支持 React/Vue 等主流前端框架,自然也继承了丰富的状态管理生态。本文将全面剖析 Taro 中的各种状态管理方案,从…

记录一下jar做成windows服务问题

1、打包好jar 2、把jdk防止到和jar同一目录下 3、下载winsw-x64.exe 和 sample-minimal.xml https://github.com/winsw/winsw/releases/download/v2.12.0/WinSW-x64.exehttps://github.com/winsw/winsw/releases/download/v2.12.0/WinSW-x64.exe sample-minimal.xmlhttps://…

【Dify 案例】【MCP实战】【二】【超级助理】

我们创建一个工作流。你是一个超级助理,能够根据输入的指令,进行推理和自主调用工具,完成并输出结果。 注意,需要判断是否调用高德MCP来获取对应工具协助你完成任务。 1.开始 2.策略大脑 2.1 AEGNT策略 2.2 工具列表 2.3 指令

Qt Quick 与 QML(二)qml中的顶级窗口

一、前言 在QML中,‌顶级窗口不是绝对必需的‌,但它在大多数应用场景中扮演着关键角色。 需要顶级窗口的典型场景: 1.独立桌面/移动应用‌ 必须使用Window或ApplicationWindow作为根元素。 2.多窗口应用 每个独立窗口都需要一个顶级窗口实例…

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 免费服务开通全流程与Rest API和OpenAI SDK调用详解

华为云FlexusDeepSeek征文|DeepSeek-V3/R1 免费服务开通全流程与Rest API和OpenAI SDK调用详解 前言 本文将详细介绍DeepSeek-V3/R1 免费服务开通全流程,并且详细讲解通过本地方式Rest API和OpenAI SDK两种方式调用DeepSeek-V3/R1 前提准备 1、访问 Mod…

Qt 连接信号使用lambda表达式和槽函数的区别

1. 语法与代码结构 成员函数 需在类中显式声明槽函数(public slots: 或 Qt 5 后的任意成员函数),并在连接时指定接收对象。 class Receiver : public QObject {Q_OBJECT public slots:void handleSignal(int value) { /* ... */ } };// 连接…

学习笔记丨AR≠VR:透视沉浸式技术的“虚实象限”法则

AR(增强现实)和VR(虚拟现实)是沉浸式技术的两大分支,核心区别在于虚拟与现实的融合程度。以下是两者的详细对比: 对比维度 AR(增强现实) VR(虚拟现实) 技术…

本地使用 modelscope 大模型 来进行文本生成视频(Text-to-Video)

1. ✅ 创建并激活 Conda 环境(Python 3.8) conda create -n modelscope python3.8 -yconda activate modelscope 2.✅ 安装了 PyTorch(CPU 版本) 如果你是 CPU-only 用户(没有 NVIDIA 显卡 或不想用 GPU&#xff0…

文生视频(Text-to-Video)

🕒 生成时间:每张图大概 10–60 秒(取决于设备) ✅ 二、文生视频(Text-to-Video) 以下项目中,很多都基于 SD 模型扩展,但视频生成复杂度高,生成时间一般 超过 30 秒&am…

CLion + STM32环境配置,亲测有效(2025.06.19记)

CLion STM32环境配置 遇到的问题描述: > "moniton" command not supported by this target. > You cant do that when your target is exec > 上传完成,但存在问题 > monitor reset > "monitor" command not …

借助ChatGPT快速开发图片转PDF的Python工具

一、开发背景与适用场景 随着数字文档处理需求的激增,图片转PDF的需求日益广泛。从学生提交图像化作业,到教师整合扫描试卷等资料,再到行政人员归档证件照片,工作中的方方面面都离不开图片的处理。如何高效、批量地将多个图片文件…

SuGAR代码精简解读

目录 一、全流程训练脚本 train_full_pipeline.py 二、核心训练逻辑 train.py 粗优化 (coarse_density_and_dn_consistency.py) 网格提取 (extract_mesh_from_coarse_sugar) 精优化 (refined_training) 两次优化(粗优化和精优化)中使用的损失函数及…

大模型安全关键技术研究

​ 引言 随着人工智能技术的迅猛发展,大模型已成为推动各行业变革的核心力量。从智能客服、医疗影像识别到金融风险预测,大模型的应用场景不断拓展,深刻改变着人们的生产生活方式。大模型已经转变为AI领域的基础设施,为解决各种…

java面试题04成员变量和局部变量的区别

成员变量(Member Variable)和局部变量(Local Variable)是面向对象编程中两种作用域和生命周期不同的变量,主要区别体现在以下几个方面: 1. 声明位置 成员变量: 声明在类内部、方法/构造器/代码块外部。 例如: public class Person {// 成员变量(实例变量)private Str…

升级到 .NET 9 分步指南

随着激动人心的 .Net 9 更新正式发布,漫长的等待终于结束了。它带来了一些令人惊叹的特性,例如改进的 LINQ 功能、HybridCache 等等。此外,凭借其卓越的性能提升、更佳的安全性、更完善的协议和更易维护的特性,它必将吸引开发者和…

day30打卡

# 导入模块 import math print("方式1:使用 import math") print(f"圆周率π的值:{math.pi}") print(f"2的平方根:{math.sqrt(2)}\n") # 导入特定项 from math import pi, sqrt print("方式2&#…