当前位置: 首页 > news >正文

【C语言深度解剖】(14):结构体内存对齐(详细配图讲解)

🤡博客主页:醉竺

🥰本文专栏:《C语言深度解剖》

😻欢迎关注:感谢大家的点赞评论+关注,祝您学有所成!


✨✨💜💛想要学习更多C语言深度解剖点击专栏链接查看💛💜✨✨ 


目录

1. 结构体内存大小计算(引例) 

2. 结构体内存对齐规则 

2.1:对齐规则1 

2.2:对齐规则2 

2.3:对齐规则3 

 2.4:对齐规则4

3. 实战 


上一篇文章中我们学习了结构体的进阶,其中介绍了结构体内存对齐的规则,由于结构体内存对齐需要讲解的篇幅较长,所以这里专门写了一篇文章来讲解。感兴趣的可以先阅读这一篇文章:

《结构体进阶学习》icon-default.png?t=N7T8https://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含义:

  1. 当结构体中的最后一个成员被正确存放后,结构体的总大小并非简单地等于从第一个成员(偏移量为0的位置)到最后一个成员最后一个字节的长度。
  2. 而是首先判断出所有成员中对齐数中的最大对齐数,c1对齐数是 1,i1 和 i2 对齐数都是 4,因此整个结构体成员中的最大对齐数是 4.
  3. 最后,如果 从第一个成员(偏移量为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):结构体内存对齐(详细配图讲解)

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多C语言深度解剖点击专栏链接查看&…...

学习笔记:C语言的32个关键字

一、标准C语言的32个关键字 1、基本数据类型&#xff1a; signed unsigned char int float double short long void 2、构造数据类型&#xff1a; struct union enum 3、数据存储类别&#xff1a; auto static extern register 4、数据优化&#xff1a; const volatile 5、9条…...

嵌入式学习 (Day:27 IPC --- 进程间通信)

IPC 进程间通信 interprocess communicate &#xff08;即&#xff1a;进程间进行数据交换&#xff09; 三大类&#xff1a; 进程间通信的方式&#xff08;共8种&#xff09; 1、古老的通信方式&#xff08;Linux设计时就有的&#xff09; 无名管道 有名…...

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】&#xff1a; map() 函数 【知识点1】&…...

整理好了!2024年最常见 20 道 Redis面试题(九)

上一篇地址&#xff1a;整理好了&#xff01;2024年最常见 20 道 Redis面试题&#xff08;八&#xff09;-CSDN博客 十七、Redis 的过期策略有哪些&#xff1f; Redis 的过期策略主要有三种&#xff1a; 定时删除&#xff1a;当为一个键设置了过期时间后&#xff0c;Redis 会…...

IDEA使用Maven打包项目的所有的依赖

要使用 Maven 命令将 Spring Boot 项目的依赖打包到 lib 文件夹中&#xff0c;你可以在终端中运行以下命令&#xff1a; mvn dependency:copy-dependencies -DoutputDirectory./lib这个命令会将项目的所有依赖&#xff08;包括运行时依赖&#xff09;复制到当前目录的 lib 文件…...

【C++ 】学习问题及补充

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

内存泄漏案例分享3-view的内存泄漏

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

红外超声波雷达测距

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

AIGC 008-IP-Adapter文本兼容图像提示适配器用于文本到图像扩散模型

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

Java入门基础学习笔记50——ATM系统

1、项目演示&#xff1b; 2、项目技术实现&#xff1b; 1&#xff09;面向对象编程&#xff1a; 每个账户都是一个对象&#xff0c;所以要设计账户类Account&#xff0c;用于创建账户对象封装账户信息。ATM同样是一个对象&#xff0c;需要设计ATM类&#xff0c;代表ATM管理系…...

# linux 中使用 visudo 命令,怎么保存退出?

linux 中使用 visudo 命令&#xff0c;怎么保存退出&#xff1f; 在 visudo 中保存并退出的方法取决于您使用的文本编辑器。通常情况下&#xff0c;visudo 会使用 vim 或 vi 或 Nano 作为默认的文本编辑器。 1、使用 Vim 或 vi 编辑器&#xff1a; 按下 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—个基本的构建块&#xff0c;它包含、填充和对齐给定设备或视口中的內容。 Bootstrap 需要一个容器元素来包裏网站的内容 我们可以使用以下两个容器类&#xff1a; .container 类用于固定宽度并支持响应式布局的容器。.container-fluid 类用…...

宝塔部署纯Vue项目,无后端

1.打包项目 生成一个dist文件夹 2.创建云服务器根目录 3.创建站点 4.上传文件 5.访问...

spring boot3整合邮件服务实现邮件发送功能

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

算法刷题day54:搜索(一)

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

深入了解Redis的过期策略和内存淘汰机制

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起进步&am…...

小白不知道怎么投稿?记住这个好方法

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

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...