【C语言深度解剖】(14):结构体内存对齐(详细配图讲解)
🤡博客主页:醉竺
🥰本文专栏:《C语言深度解剖》
😻欢迎关注:感谢大家的点赞评论+关注,祝您学有所成!
✨✨💜💛想要学习更多C语言深度解剖点击专栏链接查看💛💜✨✨
目录
1. 结构体内存大小计算(引例)
2. 结构体内存对齐规则
2.1:对齐规则1
2.2:对齐规则2
2.3:对齐规则3
2.4:对齐规则4
3. 实战
上一篇文章中我们学习了结构体的进阶,其中介绍了结构体内存对齐的规则,由于结构体内存对齐需要讲解的篇幅较长,所以这里专门写了一篇文章来讲解。感兴趣的可以先阅读这一篇文章:
《结构体进阶学习》https://blog.csdn.net/weixin_43382136/article/details/138768281
1. 结构体内存大小计算(引例)
下面实例中结构体的类型你觉得是多大? (Visual Stdio环境下)
#include <stdio.h>
struct Stu
{char name;int age;
};int main()
{printf("%d", sizeof(struct Stu));return 0;
}
初学结构体的人会认为,结构体类型的大小是其中各变量的大小之和,上述代码中结构体是 5 字节,其实并非如此!下面是运行结果: 8 (字节)
为什么输入结果是8而不是5呢?这与结构体在内存中特殊的存储方式有关,接下来就引出我们本章的主题 《结构体内存对齐》
2. 结构体内存对齐规则
1. 第一个成员存储在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
- VS中默认的值为8
- GCC环境下没有默认对齐数,此时结构体成员自身的大小就是对齐数
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
上述规则猛的一看会有点懵,什么跟什么啊?请继续往下阅读。
2.1:对齐规则1
- 第一个结构体成员在与结构体变量偏移量为0的地址处。
偏移量:结构体变量中第一个成员的地址 相对于首地址的距离。
对齐规则1中偏移量为0,就代表着结构体变量中第一个成员,是从开辟的整个结构体变量空间的首地址开始存储。
这里我们用以下结构体作为一个例子:下面结构体变量的大小为12字节
struct S1
{char c1;int i1;int i2;
};
我们一步步画图来分析 :
c1 存储位置
2.2:对齐规则2
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的值为8
GCC环境下没有默认对齐数,此时结构体成员自身的大小就是对齐数
1. 当前是VS环境下,默认对齐数是8,后面两个成员分别是 int i1, int i2,它们都是4字节,因此在VS环境下,这两个成员变量的对齐数 就是 “4”。
2. 根据规则2,其他成员变量要对齐到 "对齐数"的整数倍地址处,已知后面两个成员 i1 和 i2 对齐数是 4 ,这个规则意味着,i1 和 i2 要从偏移量为 4 的整数倍位置开始存储。具体看下图:
同理 i2 也是从 偏移量为 4 的整数倍位置开始存储,这里由图可知,需要从偏移量为 8 的位置开始存储,如下图所示:
而偏移量为“1,2,3”的空白处则会
2.3:对齐规则3
- 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
struct S1
{char c1;int i1;int i2;
};
对于上述的结构体例子,应用到规则3,其实就已经结束了,因为规则4是针对嵌套结构体的。
规则3含义:
- 当结构体中的最后一个成员被正确存放后,结构体的总大小并非简单地等于从第一个成员(偏移量为0的位置)到最后一个成员最后一个字节的长度。
- 而是首先判断出所有成员中对齐数中的最大对齐数,c1对齐数是 1,i1 和 i2 对齐数都是 4,因此整个结构体成员中的最大对齐数是 4.
- 最后,如果 从第一个成员(偏移量为0的位置)到最后一个成员最后一个字节的长度不是 最大对齐数 4 的整数倍,则整个结构体占据的总内存需要从最后一个字节继续延伸,直到整个结构体大小是 4 的整数倍。
上个例子中,最后一个成员 i2 成员存储好之后,最后一个字节的位置已经在 偏移量为 11 的位置处了,此时整个结构体变量的总大小已经是 12 了,12是 最大对齐数 4 的整数倍了,所以无需延伸,上述结构体S1类型的总大小就是12字节。
2.4:对齐规则4
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
对齐规则4 其实跟 对齐规则3类似,只不过一个判断成员变量的对齐数,一个是 整个结构体的最大对齐数。
这里我们看一个新的例子:
S2结构体大小为 20 字节
struct S1
{char c;int i1;int i2;
};struct S2
{char a;struct S1 s1; //嵌套结构体char b;
};
3. 实战
接下来会再整一个综合的例子,不再做出详细解释,看图分析即可。
S1的内存分布:
a的对齐数是4,b的对齐数是1,d的对齐数是8,因此 S1整个结构体的最大对齐数是8,总体大小为16字节。
S2的内存分布:
ch 的对齐数是1,s1 的对齐数是8, i 的对齐数是4,因此S2结构体类型最大对齐数是8.
相关文章:

【C语言深度解剖】(14):结构体内存对齐(详细配图讲解)
🤡博客主页:醉竺 🥰本文专栏:《C语言深度解剖》 😻欢迎关注:感谢大家的点赞评论关注,祝您学有所成! ✨✨💜💛想要学习更多C语言深度解剖点击专栏链接查看&…...
学习笔记:C语言的32个关键字
一、标准C语言的32个关键字 1、基本数据类型: signed unsigned char int float double short long void 2、构造数据类型: struct union enum 3、数据存储类别: auto static extern register 4、数据优化: const volatile 5、9条…...
嵌入式学习 (Day:27 IPC --- 进程间通信)
IPC 进程间通信 interprocess communicate (即:进程间进行数据交换) 三大类: 进程间通信的方式(共8种) 1、古老的通信方式(Linux设计时就有的) 无名管道 有名…...

Python考试复习--day2
1.出租车计费 mile,waitmap(int,input().split(,)) if mile<3:money13wait*1 elif mile>3 and mile<15:money13(mile-3)*2.3wait*1 else:money1312*2.3(mile-15)*2.3*(10.5)wait*1 print({:.0f}.format(money)) 【知识点1】: map() 函数 【知识点1】&…...
整理好了!2024年最常见 20 道 Redis面试题(九)
上一篇地址:整理好了!2024年最常见 20 道 Redis面试题(八)-CSDN博客 十七、Redis 的过期策略有哪些? Redis 的过期策略主要有三种: 定时删除:当为一个键设置了过期时间后,Redis 会…...
IDEA使用Maven打包项目的所有的依赖
要使用 Maven 命令将 Spring Boot 项目的依赖打包到 lib 文件夹中,你可以在终端中运行以下命令: mvn dependency:copy-dependencies -DoutputDirectory./lib这个命令会将项目的所有依赖(包括运行时依赖)复制到当前目录的 lib 文件…...

【C++ 】学习问题及补充
一.自定义类型不初始化直接就赋值,比如string类会怎么样 vectr<string>里已经给每个string对象已经分配好空间,为什么不初始化再赋值会报错 在C中,std::string类是一个动态字符串类,它内部管理着一个字符数组,用…...

内存泄漏案例分享3-view的内存泄漏
案例3——view内存泄漏 前文提到,profile#Leaks视图无法展示非Activity、非Fragment的内存泄漏,换言之,除了Activity、Fragment的内存泄漏外,其他类的内存问题我们只能自己检索hprof文件查询了。 下面有一个极佳的view内存泄漏例子…...

红外超声波雷达测距
文章目录 一HC-SR04介绍1HC-SR04简介及工作原理 二用HAL库实现HC-SR04测量距离1STM32CubeMX配置2keil53代码的添加 三效果 一HC-SR04介绍 1HC-SR04简介及工作原理 超声波是振动频率高于20kHz的机械波。它具有频率高、波长短、绕射现象小、方向性好、能够成为射线而定向传播等…...

AIGC 008-IP-Adapter文本兼容图像提示适配器用于文本到图像扩散模型
AIGC 008-IP-Adapter文本兼容图像提示适配器用于文本到图像扩散模型! 文章目录 0 论文工作1 论文方法2 效果 0 论文工作 这篇论文介绍了 IP-Adapter,一种 高效地将预训练的图像到图像转换模型适应到新领域 的方法。它通过在预训练模型的 输入端 添加一个…...

Java入门基础学习笔记50——ATM系统
1、项目演示; 2、项目技术实现; 1)面向对象编程: 每个账户都是一个对象,所以要设计账户类Account,用于创建账户对象封装账户信息。ATM同样是一个对象,需要设计ATM类,代表ATM管理系…...
# linux 中使用 visudo 命令,怎么保存退出?
linux 中使用 visudo 命令,怎么保存退出? 在 visudo 中保存并退出的方法取决于您使用的文本编辑器。通常情况下,visudo 会使用 vim 或 vi 或 Nano 作为默认的文本编辑器。 1、使用 Vim 或 vi 编辑器: 按下 Esc 键退出编辑模式&…...

springboot项目,@Test写法 @Before @After
某文件示例 package cn.xxx.crm.boss;import cn.xxxx.crm.manager.mq.rabbit.AliyunCredentialsProvider; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; im…...

vue3的核心API功能:computed()API使用
常规使用方法: 这样是常规使用方法. 另一种,可写计算属性的使用方法: 这样分别定义computed的get回调函数和set回调函数, 上面例子定义了plusOne.value的值为1, 那么这时候就走了computed的set回调函数,而没有走get回调函数. 当我们打印plusOne.value的值的时候,走的是get的…...

Bootstrap5
Bootstrap5-容器 容器是Bootstrap—个基本的构建块,它包含、填充和对齐给定设备或视口中的內容。 Bootstrap 需要一个容器元素来包裏网站的内容 我们可以使用以下两个容器类: .container 类用于固定宽度并支持响应式布局的容器。.container-fluid 类用…...

宝塔部署纯Vue项目,无后端
1.打包项目 生成一个dist文件夹 2.创建云服务器根目录 3.创建站点 4.上传文件 5.访问...

spring boot3整合邮件服务实现邮件发送功能
⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 目录 内容概要 开通服务 依赖引入 配置属性 创建邮件发送工具类 测试 最近发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家…...

算法刷题day54:搜索(一)
目录 引言一、池塘计数二、城堡问题三、山峰和山谷四、迷宫问题五、武士风度的牛六、抓住那头牛七、矩阵距离八、魔板 引言 针对于蓝桥杯,搜索问题还是非常之重要的,在省赛前深知暴搜的重要性,所以提前先把提高课的搜索一章给看了࿰…...

深入了解Redis的过期策略和内存淘汰机制
✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 ✨✨ 帅哥美女们,我们共同加油!一起进步&am…...

小白不知道怎么投稿?记住这个好方法
作为一名单位信息宣传员,我最初踏上这条道路时,满心憧憬着通过文字传递我们单位的精彩瞬间,让社会听见我们的声音。然而,理想与现实之间的距离,却在一次次邮箱投稿的石沉大海中渐渐清晰。那时的我,像所有“小白”一样,以为只要用心撰写稿件,通过电子邮件发给各大媒体,就能收获满…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...