C语言字节对齐关键字__attribute__((aligned(n)))的使用

0 前言

在进行嵌入式开发的过程中,我们经常会见到对齐操作。这些对齐操作有些是为了便于实现指针操作,有些是为了加速对内存的访问。因此,学习如何使用对齐关键字是对于嵌入式开发是很有必要的。

1 对齐规则

1.0 什么叫做对齐

众所周知,内存的最小单位是字节。理论上,CPU可以访问内存上任意地址的数据,但实际上数据在内存中的分布并不是随意的,它们往往会遵循一定的对齐规则,使CPU访问这些数据的速度提升。
对齐实际上就是将变量存储的首地址按照1、2、4、8字节对齐,如果按照2字节对齐则变量在内存中的首地址必须是2的倍数,其它字节对齐方式也是如此。

1.1 默认的对齐方式

根据使用处理器、编译器的不同,变量在内存中的地址对齐方式不同。例如常见的STM32默认4字节对齐,本文使用的x64+vscode环境默认8字节对齐。

1.2 关键字attribute((aligned(n)))介绍

__attribute__((aligned(n)))
__attribute__((packed))

(1)attribute((aligned(n))):它的作用是对结构体整体进行n(n必须是2的幂)字节对齐,而不是为结构体成员进行对齐(使用结构体成员最大占用字节和指定字节对齐大小中最大的那个作为对齐标准)。它可以针对某个结构体进行对齐,也可以写在外部,对其后面的所有变量进行对齐操作
(2)attribute((packed)):按照1字节对齐(取消对齐)

2 实例测试

2.1 结构体成员默认的对齐方式

测试说明:
这里使用的是64位电脑,经过vscode后默认的对齐方式为按8字节对齐。
示例程序:

#include "stdio.h"typedef struct
{unsigned char a;unsigned short int b;unsigned int c;double d;
} test_t;
test_t test;
int main(void)
{printf("a addr : 0x%x\r\n", &test.a);printf("b addr : 0x%x\r\n", &test.b);printf("c addr : 0x%x\r\n", &test.c);printf("d addr : 0x%x\r\n", &test.d);return 0;
}

我们这里定义了1个名为test_t的结构体,成员a、b、c、d的大小分别为1、2、4、8字节。在不做任何对齐操作下,打印a、b、c、d在内存上的地址:
在这里插入图片描述

可以看到,成员在结构体的分布对齐方式分别是1、2、4、8字节,同时结构体首地址也就是成员a的地址是按照8字节对齐的。它们在内存中的分布可以用如下示意图表示:
在这里插入图片描述

2.2 设置结构体成员按照1字节对齐

测试说明:
这里使用的是64位电脑,经过vscode后默认的对齐方式为按8字节对齐。
示例程序:

typedef struct __attribute__((packed))
{unsigned char a;unsigned short int b;unsigned int c;double d;
} test_t;
test_t test;int main(void)
{printf("a addr : 0x%x\r\n", &test.a);printf("b addr : 0x%x\r\n", &test.b);printf("c addr : 0x%x\r\n", &test.c);printf("d addr : 0x%x\r\n", &test.d);return 0;
}

我们这里定义了1个名为test_t的结构体,成员a、b、c、d的大小分别为1、2、4、8字节。在按照1字节对齐之后,打印a、b、c、d在内存上的地址:
在这里插入图片描述
可以看到,成员在结构体的分布对齐方式是1字节,同时结构体首地址也就是成员a的地址是按照1字节对齐的。可以用如下的示意图表示使用__attribute__((packed))前后结构体成员在内存中的分布:
在这里插入图片描述

2.3 设置结构体变量32字节对齐

示例程序:

#include "stdio.h"
__attribute__((aligned(32)))
typedef struct
{unsigned char a;unsigned short int b;unsigned int c;double d;
} test_t;
test_t test;int main(void)
{printf("a addr : 0x%x\r\n", &test.a);printf("b addr : 0x%x\r\n", &test.b);printf("c addr : 0x%x\r\n", &test.c);printf("d addr : 0x%x\r\n", &test.d);return 0;
}

我们这里定义了1个名为test_t的结构体,成员a、b、c、d的大小分别为1、2、4、8字节。在按照1字节对齐之后,打印a、b、c、d在内存上的地址:
在这里插入图片描述
可以看到,结构体首地址也就是成员a的地址是按照32字节对齐的。可以用如下的示意图表示使用__attribute__((aligned(32)))前后结构体及其成员在内存中的分布:
在这里插入图片描述

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

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

相关文章

谈谈变压器中的位置编码

变压器中的位置编码 一、说明 在上一期的“Transformers for Everyone”系列中,我们介绍了 Transformer 的概念,并深入研究了第一个关键架构元素:输入嵌入。如果你错过了第一集,你可以通过阅读来赶上:适合所有人的变形…

IRIS / Chronicles 数据库结构

对于我们用得最多的关系型数据库来说,首先有的是数据库名字,然后是表名字,然后就是字段名,随后就是一条一条的数据。 对于 IRIS 来说,因为是使用的层级数据库,所以上面的定义就不能完全的照搬了&#xff0…

【傅里叶变换、短时傅里叶变换、小波变换】

傅里叶:可以知道信号中的成分,但对非平稳过程,不能看出各成分出现的时刻短时傅里叶变换-:加固定窗的傅里叶变换,无法满足非稳态信号变化的频率的需求小波变换:时域能量有限,频域带通滤波 一、傅…

系统可靠性分析与设计相关知识总结

一、软件可靠性定义 软件可靠性使软件产品在规定的条件下和规定的时间区间内完成规定的功能的能力。是软件系统在应用或系统错误面前,在意外或错误使用的情况下维持软件系统功能特性的基本能力。 规定的条件:直接与软件运行相关的使用该软件的计算机系统…

husky配置实现代码提交前校验与规范提交信息

husky是一个Git Hook管理工具,主要用于实现提交前eslint校验和commit信息的规范校验。 Husky 的原理是让我们在项目根目录中写一个配置文件,然后在安装 Husky的时候把配置文件和 Git Hook 关联起来,这样我们就能在团队中使用 Git Hook 了。 …

Matplotlib数据可视化实战-2绘制折线图(2)

2.11营业额可视化 已知某学校附近一个烧烤店2022年每个月的营业额如下图所示。编写程序绘制折线图对该烧烤店全年营业额进行可视化,使用红色点画线连接每个月的数据,并在每个月的数据处使用三角形进行标记。 烧烤店营业额 月份123456789101112营业额/万…

Redis - 5k star! 一款简洁美观的 Redis 客户端工具~

项目简介 Tiny RDM 是一款现代化、轻量级的跨平台 Redis 桌面客户端,可在 Mac、Windows 和 Linux 系统上运行。初次打开 Tiny RDM,你会被它舒适的风格和配色所吸引,界面简约而不简单,功能齐全。 Tiny RDM 有着如下的功能特性 项…

男生t恤什么牌子好?男士T恤品牌推荐?

很多男士朋友最近都打算准备一套春夏季穿的短袖,但奈何当前的市场上充斥着大量低劣质的衣裤。这些产品的质量普遍不耐穿、耐洗,并且版型不好等情况。为此我特意为大家整理五个质量好且价格不贵的五个男装品牌。希望能够帮助到大家挑选到合适的短袖。 因为…

保研线性代数机器学习基础复习1

1.什么是代数(algebra)? 为了形式化一个概念,构建出有关这个概念的符号以及操作符号的公式。 2.什么是线性代数(linear algebra)? 一项关于向量以及操作向量的公式的研究。 3.举一些向量的例子&#x…

【opencv】教程代码 —ImgProc (7)使用维纳滤波器来恢复失焦的图像

7. out_of_focus_deblur_filter.cpp使用维纳滤波器来恢复失焦的图像 代码的主要功能是通过使用维纳滤波器来恢复失焦的图像,它读取一个灰度图像文件,对其进行滤波操作,并将结果保存为新文件。这个过程包括计算点扩散函数(PSF),执行…

机器学习模型——KNN

KNN的基本概念: KNN(K-Nearest Neighbor)就是k个最近的邻居的意思,即每个样本都可以用它最接近的k个邻居来代表。KNN常用来处理分类问题,但也可以用来处理回归问题。 核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某…

python实现在线 ChatGLM调用

python实现在线 ChatGLM调用 1. 申请调用权限: 收钱进入到质谱AI开放平台,点击“开始使用”或者“开发者工具台”进行注册: 对于需要使用 API key 来搭建应用的话,需要点击右边红框中的查看 API key,就会进入到我们…

yolov8 pose keypoint解读

yolov8进行关键点检测的代码如下: from ultralytics import YOLO# Load a model model YOLO(yolov8n.pt) # pretrained YOLOv8n model# Run batched inference on a list of images results model([im1.jpg, im2.jpg]) # return a list of Results objects# Pr…

读所罗门的密码笔记04_社会信用

1. 人工智能 1.1. 人工智能可以帮助人们处理复杂的大气问题,完善现有的气候变化模拟,帮助我们更好地了解人类活动对环境造成的危害,以及如何减少这种危害 1.2. 人工智能也有助于减少森林退化和非法砍伐 1.3. 人工智能甚至可以将我们从枯燥…

RISC-V特权架构 - 中断定义

RISC-V特权架构 - 中断定义 1 中断类型1.1 外部中断1.2 计时器中断1.3 软件中断1.4 调试中断 2 中断屏蔽3 中断等待4 中断优先级与仲裁5 中断嵌套6 异常相关寄存器 本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 1 中断类型 RISC-V 架构定义的中…

idea打开文件乱码,设置编码

idea整个项目都设置了utf-8了,但是还是有一个文件是其他编码_(ཀ」 ∠)__ 。 配置项目编码 在设置中设置编码 配置具体目录的编码 上面的设置之后,还是有几个文件一直是乱码,需要单独配置。 偶尔引入的依赖中的文件也会乱码,需…

题目:摆花(蓝桥OJ 0389)

问题描述&#xff1a; 题解&#xff1a; #include <bits/stdc.h> using namespace std; using ll long long; const int N 105; const ll p 1e6 7; ll a[N], dp[N][N];int main() {int n, m; cin >> n >> m;for(int i 1; i < n; i)cin >> a[i…

【科研基础】VAE: Auto-encoding Variational Bayes

[1]Kingma, Diederik P., and Max Welling. “Auto-encoding variational bayes.” arXiv preprint arXiv:1312.6114 (2013). [2] [论文简析]VAE: Auto-encoding Variational Bayes[1312.6114] [3] The Reparameterization Trick [4] 变分法的基本原理是什么? 文章目录 1-…

我的编程之路:从非计算机专业到Java开发工程师的成长之路 | 学习路线 | Java | 零基础 | 学习资源 | 自学

小伙伴们好&#xff0c;我是「 行走的程序喵」&#xff0c;感谢您阅读本文&#xff0c;欢迎三连~ &#x1f63b; 【Java基础】专栏&#xff0c;Java基础知识全面详解&#xff1a;&#x1f449;点击直达 &#x1f431; 【Mybatis框架】专栏&#xff0c;入门到基于XML的配置、以…

负荷频率控制LFC,自抗扰ADRC控制,麻雀SSA算法优化自抗扰参数,两区域二次调频simulink/matlab

红色曲线为优化结果&#xff0c;蓝色曲线为没有自抗扰和没有优化的结果&#xff01;