广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >一篇文章带你了解C语言内存对齐
  • 805
分享到

一篇文章带你了解C语言内存对齐

2024-04-02 19:04:59 805人浏览 八月长安
摘要

目录内存对齐三、在内存对齐话题下的sizeof与offsetof宏3.1、sizeof3.2、offsetof宏3.3、Debug总结内存对齐 先看如下代码: 结构体Test1

内存对齐

先看如下代码:

在这里插入图片描述

结构体Test1占用了多少字节?如果事先不知道内存对齐的话,答案肯定是:1个字节(char)+ 4个字节(int)+ 1个字节(char) = 6个字节。

事实上,Test1结构体占用了12个字节,从DEBUG模式下Watch1观察:

在这里插入图片描述

OK,不就猜少了6个字节吗?有什么影响吗?先不说影响吧,咱们先来看看单片机内存里的实际情况。从上图看到,结构体变量的首地址是0x200018F4,通过Keil的Memory1可以看到结构体Text1在内存的分布,如下图所示。

在这里插入图片描述

将Test1的内存分布提取出来,如下图所示,因为内存对齐的原因,有6个字节被填充了。换句话说,这6个字节被浪费了,无法被其他资源使用了(因为编译器将这些内存规划给结构体Test1了)。此时,如果使用结构体Text1在堆内存大量地定义变量的话,将会造成非常严重的内存浪费(内存碎片化),浪费的内存 = 6 * N(N表示结构体变量的个数)。比如用结构体Text1定义1000个结构体变量,浪费的内存 = 6 * 1000 = 6000 Byte(非常接近6K内存)。

在这里插入图片描述

好了,假如我是懂得内存对齐的原理的,那么我可以这样去优化结构体Text1。

在这里插入图片描述

接着,从Debug里观察看看:

在这里插入图片描述

最后,去Memory1观察内存的分布情况:

在这里插入图片描述

再将结构体Text1的内存分布提取出来分析一下,将成员b与成员c互换位置后,被填充的字节数变成2,成功地优化了4个字节的碎片。如果用Text1的结构体去定义1000个结构体变量的话,那么1000 * 6的碎片内存被优化成1000 * 2的碎片内存,成功改善了1000 * 4(接近4K的内存)啊。

在这里插入图片描述

三、在内存对齐话题下的sizeof与offsetof宏

首先,在main.c包含头文件stddef.h。

在这里插入图片描述

回到最初的例子,代码如下:

在这里插入图片描述

3.1、sizeof

通过sizeof操作符能够得出一个结构的整体长度,包括因边界对齐而跳过的那些字节。

在这里插入图片描述

3.2、offsetof宏

考虑到内存对齐的因素,想确定结构体里某个成员的实际位置,可以使用offsetof宏得到。比如我想得到成员b在结构体Test1的实际位置(包括内存对齐因素)。

在这里插入图片描述

3.3、Debug

进入Debug模式观察sizeof与offsetof的返回值分别是12与4。

在这里插入图片描述

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: 一篇文章带你了解C语言内存对齐

本文链接: https://www.lsjlt.com/news/132617.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 一篇文章带你了解C语言内存对齐
    目录内存对齐三、在内存对齐话题下的sizeof与offsetof宏3.1、sizeof3.2、offsetof宏3.3、Debug总结内存对齐 先看如下代码: 结构体Test1...
    99+
    2022-11-12
  • 一篇文章带你了解C语言内存对齐公式
    目录一、前言二、公式2.1、例子一2.2、例子二2.3、例子三总结一、前言 每一个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。GCC中默认#program pack...
    99+
    2022-11-12
  • 一篇文章带你了解C语言内存对齐解决的问题
    目录一、内存对齐为4个字节的好处二、内存对齐的目的是以空间换取速度2.1、内存对齐为4的例子2.2、内存没有使用内存对齐的例子CPU读取数据的过程:三、掌握内存对齐的必要性总结一、内...
    99+
    2022-11-12
  • 一篇文章带你了解C语言--数据的储存
    目录前言数据类型介绍类型的基本归类整形在内存中的存储原码、反码、补码大小端介绍浮点型在内存中的存储前言 前面我们学习了C语言的一些基本知识和基础的语法,想必大家对C语言都有了自己的认...
    99+
    2022-11-12
  • 一篇文章带你了解C语言操作符
    目录一、操作符分类 二、算术操作符三、移位操作符1、左移操作符 2、右移操作符2.1算术移位 2.2逻辑移位 四、位操作符 1、按位...
    99+
    2022-11-12
  • 一篇文章带你了解C语言函数递归
    目录什么是递归?递归的两个必要条件递归实例实例1(按照顺序打印一个数的整形值)画图讲解 完整代码 实例2 (使用函数在不创建变量的情况下求字符串长度)画图讲解程序...
    99+
    2022-11-13
  • 一篇文章带你了解C语言:入门基础
    目录C语言本身特点数据类型常量变量变量分类使用小建议生命周期作用域常量分类及其特点字符串+转义字符+注释字符串转义字符两种注释选择循环语句函数数组总结闲话少说,先上思维导图。 如图...
    99+
    2022-11-12
  • 一篇文章带你了解C语言指针进阶
    目录1.字符指针2.指针数组3.数组指针4.函数指针5.数组传参总结1.字符指针 我们已经知道了数组名在大部分时候表示数组的地址,指针本质上也表示一个地址,那么我们能否用指针来创建一...
    99+
    2022-11-12
  • 一篇文章带你了解C语言二分查找
    目录总结我们常常需要对数据进行查找,修改,查找数据有许多方法,我们先看看最简单的顺序查找 int main() { int i, k = 0; scanf("%d", &am...
    99+
    2022-11-12
  • 一篇文章带你了解C语言的文件操作
    目录为什么使用文件什么是文件程序文件数据文件文件名文件的打开和关闭文件指针fopen和fclose函数文件的顺序读写总结为什么使用文件 我们在想既然是通讯录就应该把信息记录下来,只有...
    99+
    2022-11-13
  • 一篇文章带你了解C语言中volatile关键字
    目录C语言中volatile关键字总结C语言中volatile关键字 volatile关键字是C语言中非常冷门的关键字,因为用到这个关键字的场景并不多。 当不用这个关键字的时候,CP...
    99+
    2022-11-12
  • 一篇文章带你了解C语言:入门基础(2)
    目录操作符算术操作符移位操作符位操作符单目操作符逻辑反操作!操作符++,--逻辑操作符条件操作符逗号表达式常见关键字typedefexternstatic修饰局部变量修饰全局变量和函...
    99+
    2022-11-12
  • 一篇文章带你了解C语言的选择结构
    目录一、if-else语句1.单选择 2.双选择3.多选择二.switch语句总结一、if-else语句 1.单选择 单选择通过if语句就可以实现,if语句的语法及执行流程...
    99+
    2022-11-12
  • 一篇文章带你了解JVM内存模型
    目录1. JVM介绍 1.1 什么是JVM?1.2 JVM的优点 1.2.1 一次编写,到处运行。1.2.2 自动内存管理,垃圾回收机制。1.2.3 数组下标越界...
    99+
    2022-11-12
  • 一篇文章带你了解C语言的一些重要字符串与内存函数
    目录一.字符串函数1. 求字符串长度的strlen2.比较字符串大小的strcmp3.复制字符串的strcpy4.追加字符串的strcat5.查找字符串函数的strstr二、内存函数...
    99+
    2022-11-12
  • 一篇文章带你使用C语言编写内核
    目录gcc 命令文件头将内核载入内存总结gcc 命令 使用 gcc 编译 c语言 -c 编译、汇编到目标代码,不进行链接,也就是直接生成目标文件 -o 将输出...
    99+
    2022-11-12
  • 一篇文章带你了解JavaScript-对象
    目录创建对象对象直接量通过new创建对象原型Object.create()属性的查询和设置继承属性访问错误删除属性检测属性序列化对象总结创建对象 对象直接量 对象直接量是由若干名/值...
    99+
    2022-11-12
  • 一篇文章带你了解JavaScript-语句
    目录表达式语句复合语句和空语句复合语句空语句声明语句varfunction条件语句ifif/elseelse ifswitch循环whiledo/whileforfor/in跳转标签...
    99+
    2022-11-12
  • 一篇文章带你了解C语言函数的可重入性
    目录一、不可重入函数。二、可重入函数。三、如何写出可重入的函数四、函数的可重入性和线程安全的关系五、malloc和printf为什么不可重入总结一、不可重入函数。 在函数中如果我们使...
    99+
    2022-11-12
  • 一篇文章带你入门C语言:数组
    目录数组一维数组初始化使用总结:内存存储二维数组创建初始化数组越界问题数组作函数参数应用实例总结数组 一维数组 创建 定义 数组是一组相同类型的元素的集合。那数组的语法形式: t...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作