一篇文章带你了解C语言内存对齐解决的问题
目录
- 一、内存对齐为4个字节的好处
- 二、内存对齐的目的是以空间换取速度
- 2.1、内存对齐为4的例子
- 2.2、内存没有使用内存对齐的例子
- CPU读取数据的过程:
- 三、掌握内存对齐的必要性
- 总结
一、内存对齐为4个字节的好处
首先,了解一下CPU从内存里读取数据的流程:
第一步,CPU通过地址总线,找到该数据的位置。
第二步,通过控制总线,发送读取数据的指令。
第三步,通过数据总线,从内存里获取该数据的内容。
内存对齐使用4个字节的原因有:
1.STM32单片机的数据总线与地址总线都是32bit(4个字节)。
2.方便DMA的搬运,DMA搬运的最大内存是32bit(4个字节)。
二、内存对齐的目的是以空间换取速度
2.1、内存对齐为4的例子
/* 先来一个简单的结构体 */ struct { char a; int b; }Test2;
CPU读取内存里数据的过程:
1.想找变量a:第一次读取就能找到。
2.想找变量b:第二次读取就能找到。
这一点很重要,变量a与变量b各自只需要1次寻址就能完成读取。接下来看一看内存如果没有使用内存对齐的例子(当我不知道内存对齐时,我也是误以为内存里的数据是这样分布的!)
2.2、内存没有使用内存对齐的例子
如果内存没有使用内存对齐的话,构想的内存分布如下:
CPU读取数据的过程:
1.想找变量a:第一次读取就能找到。
2.想找变量b:先读取第一组内存的后三个字节,接着再读取第二组内存的第一个字节,最后将所有字节合并为4个字节。
如果内存没有使用内存对齐的话,CPU为了获取变量b花掉了两次地址寻址,接着还要将字节合并。所以,内存对齐可以有效地提高CPU读写内存的速度,但是浪费一点空间。
三、掌握内存对齐的必要性
了解内存对齐的作用后,就能弄懂为什么编译器要对某些内存做了填充。比如本章节的例子,如果结构体里只有一个char与int变量,无论是char变量在前,还是int变量在前,都肯定会浪费3个字节被用于填充,凑够4个字节变成一组数据被CPU一次性读取。
总结
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我们的更多内容!
相关推荐
-
一篇文章带你了解C语言内存对齐
目录 内存对齐 三.在内存对齐话题下的sizeof与offsetof宏 3.1.sizeof 3.2.offsetof宏 3.3.Debug 总结 内存对齐 先看如下代码: 结构体Test1占用了多少字节?如果事先不知道内存对齐的话,答案肯定是:1个字节(char)+ 4个字节(int)+ 1个字节(char) = 6个字节. 事实上,Test1结构体占用了12个字节,从DEBUG模式下Watch1观察: OK,不就猜少了6个字节吗?有什么影响吗?先不说影响吧,咱们先来看看单片机内存里的实际情况
-
C语言中结构体与内存对齐实例解析
1.结构体类型 C语言中的2种类型:原生类型和自定义类型,结构体类型是一种自定义类型. 2.结构体使用时先定义结构体类型再用类型定义变量 -> 结构体定义时需要先定义结构体类型,然后再用类型来定义变量. -> 也可以在定义结构体类型的同时定义结构体变量. // 定义类型 struct people { char name[20]; int age; }; // 定义类型的同时定义变量. struct student { char name[20]; int age; }s1; // 将类型st
-
C语言重难点之内存对齐和位段
一:结构体内存对齐 (1)为什么要存在内存对齐 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的:某些平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常. 比如,当一个平台要取一个整型数据时只能在地址为4的倍数的位置取得,那么这时就需要内存对齐,否则无法访问到该整型数据. 性能原因: 数据结构(尤其是栈)应该尽可能的在自然边界上对齐.原因在于,为了访问未对齐内存,处理器需要作两次内存访问:而对齐的内存访问仅需一次. 核心思想就是:以空间换取时间 举个例子:对于有
-
一篇文章带你了解C语言内存对齐公式
目录 一.前言 二.公式 2.1.例子一 2.2.例子二 2.3.例子三 总结 一.前言 每一个特定平台上的编译器都有自己的默认"对齐系数"(也叫对齐模数).GCC中默认#program pack(4),即4个字节的内存对齐.Keil也是采用4字节对齐的.也可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数,一般情况下尽量使用自然对齐系数,不要修改它. STM32单片机上各个变量占用的字节数: 二.公式 公式一.结构体变量里,成员的起始地址必须
-
C语言中结构体、联合体的成员内存对齐情况
前言 最近项目进行中,遇到一个小问题,在数据协议传输过程中,我为了方便解析,就定义了一个结构体,在数据的指针传入函数的时候,我用定义好的结构体进行强制转化,没想到一直解析失败,调试很久,终于反应过来,在用结构体指针对数据强制转换时,定义结构体我没有注意到数据对齐,因为在底层实现中,我传入的数据buffer是排列整齐的,而强制转化的结构体格式中,我定义的时候没有使用__attribute__((__packed__))或者__packed强制数据对齐,导致结构体成员真实排列会按照成员中最大的变量的
-
一篇文章带你了解C语言内存对齐解决的问题
目录 一.内存对齐为4个字节的好处 二.内存对齐的目的是以空间换取速度 2.1.内存对齐为4的例子 2.2.内存没有使用内存对齐的例子 CPU读取数据的过程: 三.掌握内存对齐的必要性 总结 一.内存对齐为4个字节的好处 首先,了解一下CPU从内存里读取数据的流程: 第一步,CPU通过地址总线,找到该数据的位置. 第二步,通过控制总线,发送读取数据的指令. 第三步,通过数据总线,从内存里获取该数据的内容. 内存对齐使用4个字节的原因有: 1.STM32单片机的数据总线与地址总线都是32bit(4
-
一篇文章带你了解C语言的一些重要字符串与内存函数
目录 一.字符串函数 1. 求字符串长度的strlen 2.比较字符串大小的strcmp 3.复制字符串的strcpy 4.追加字符串的strcat 5.查找字符串函数的strstr 二.内存函数 1.复制 memcpy,memmove 2.比较 memcmp 总结 一.字符串函数 1. 求字符串长度的strlen size_t strlen ( const char * str ); 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '
-
一篇文章带你入门C语言:操作符
目录 操作符 分类 算术操作符 移位操作符 整数存储规则 左右移位规则 赋值操作符 单目操作符 取地址操作符& 解引用操作符* 类型长度操作符sizeof 按位取反操作符~ ++ -- 操作符 强制类型转换操作符(type) 关系操作符= 逻辑操作符 短路运算 条件操作符 逗号表达式 下标引用.函数调用和结构成员 下标引用操作符[] 函数调用操作符() 结构成员操作符. -> 结构体定义 结构体使用 结构体地址 表达式求值 隐式类型转换 整型提升 如何整型提升 有符号数 无符号数 算术转换
-
一篇文章带你了解C语言:入门基础(2)
目录 操作符 算术操作符 移位操作符 位操作符 单目操作符 逻辑反操作! 操作符++,-- 逻辑操作符 条件操作符 逗号表达式 常见关键字 typedef extern static 修饰局部变量 修饰全局变量和函数 其它 #define定义常量和宏 定义常量 定义宏 指针 内存单元 指针变量 &取地址操作符,*解引用操作符 类型所占空间 结构体 定义结构体 使用结构体变量 总结 本节将结束对初识C语言的概述,只追求大概,不求精细. 本节包括的内容有操作符,常见关键字,#define定义常量和宏
-
一篇文章带你了解C语言--数据的储存
目录 前言 数据类型介绍 类型的基本归类 整形在内存中的存储 原码.反码.补码 大小端介绍 浮点型在内存中的存储 前言 前面我们学习了C语言的一些基本知识和基础的语法,想必大家对C语言都有了自己的认识. 当然只是学习这些知识还是不够的,我们需要进行更加深入的学习. 从本章开始,我们将进行C语言进阶阶段的学习,所以难度会有所增加. 数据类型介绍 前面我们已经学习了基本的内置类型: char //字符数据类型 short //短整型 int //整形 long //长整型 long long //更
-
一篇文章带你入门C语言:函数
目录 函数 定义 库函数 定义 介绍 Example 1 strcpy Example 2 memset 自定义函数 Example 1 Example 2 两数交换 链式访问 Example 1 函数声明 函数递归 Example 1 Example 2 函数迭代 Example 3 Example 4 总结 函数 定义 程序里的函数又被叫做子程序,他作为一个大型程序的部分代码,有一或多个语句项组成.函数负责完成某项特定任务,提供了对过程的封装和对细节的隐藏,这样的代码通常会被集成为软件库.
-
一篇文章带你入门C语言数据结构:绪论
目录 绪论 什么是数据结构? Example 1 讨论 Example 2 Example 3 Example 4 总结 绪论 什么是数据结构? 不同于计算机操作培训,注意与程序设计的区别. Example 1 求n个数的最大值.次最大值. //1.遍历 - 最朴素的方法 int main() { int arr[10] = { 22,334,552,1,4,6,78,23,55,98 }; int i = 0; int temp = 0; int max1 = arr[0]; int max2
-
一篇文章带你了解C语言浮点数之间的比较规则
目录 你认为这段代码输出什么? 为什么不等于呢? 应该怎么解决? 那么怎么判断两个浮点数 f1 和 f2 相等呢. 伪代码 可以简化为 >> 怎么判断浮点数等于0? 还有一个问题 总结 你认为这段代码输出什么? int main() { float f1 = 1.1; float f2 = 2.2; if (f2 - 1.1 == f1) printf("等于"); else printf("不等于"); return 0; } 答案是不等于. 为什么不
随机推荐
- Linux 中的Setfacl命令
- 详解让sublime text3支持Vue语法高亮显示的示例
- JavaScript数据类型判定的总结笔记
- tomcat6.0 /7.0安装版内存溢出设置方法
- 清除3389远程桌面连接记录的批处理
- 光标的帖子总结(Range的使用)
- JavaScript中的操作符==与===介绍
- Thinkphp框架中D方法与M方法的区别
- php隐藏实际地址的文件下载方法
- 使用PHP实现微信摇一摇周边红包
- jQuery Selectors(选择器)的使用(一、基本篇)
- JScript中调用ActiveX获取访客网卡MAC地址实现代码
- javascript同步服务器时间和同步倒计时小技巧
- C#中把Datatable转换为Json的5个代码实例
- JS图片预加载插件详解
- dos批量替换当前目录后缀名的实现代码
- jQuery插件ImgAreaSelect实现头像上传预览和裁剪功能实例讲解一
- JQuery Ajax WebService传递参数的简单实例
- java二叉查找树的实现代码
- nginx实现请求转发