详解结构体内存对齐
目录
前言
一、内存大小的计算
1.规则
2.练习
二、为什么要有内存对齐
1.移植原因
2.性能原因
三、修改默认对齐数
总结
前言
本文针对结构体大小的计算进行深度剖析。结构体的大小要遵守内存对齐,在绝大数情况下,会浪费空间。但是有其的价值,仔细阅读本文,将会对内存对齐有深刻的认识,知其本因。
一、内存大小的计算
1.规则
1. 第一个成员在与结构体变量偏移量为0的地址处
2. 从第二个成员开始,以后每个成员都要对齐到某个对齐数的整数倍位置
这个对齐数是自身成员大小和默认成员对齐数的较小值
备注:
vs环境下默认成员对齐数是8
3.当成员全部放入后,结构体的总大小必须是所有成员对齐数中最大对齐数的整数倍
4.如果嵌套了结构体,嵌套的结构体成员要对齐到自己成员的最大对齐数的整数倍处。
整个结构体的大小,必须是最大对齐数的整数倍,最大对齐数包含嵌套结构体的对齐数。
以上这是最常见的计算,下面我将通过就几道题帮大家理解
2.练习
1)计算大小
struct S1
{char c1;int i;char c2;
};
答案:12
详解:
以32位系统为例子
第一个char 类型c1 大小为1,放在偏移量为0的位置上第二个元素为int 大小为4,要放在某个对齐数上,这个对齐数是自身4和默认对齐数8的较小值 4 .所以i要放在4的倍数上,离i最近的位置偏移量为4,所以之前浪费了三个空间
第三个元素c2,要放在自身大小1和默认对齐数8的较小值1的倍数上,由于i以及占用了7的位置,所以c2要放在偏移量为8的位置上,总计大小为1+3+4+1=9
最后计算总结构体的大小,成员最大对齐数是4 ,但是上述分析为9,不满足4的倍数,就要浪费3个空间,到12上。
下面就通过一张图解来帮助理解

2)、计算大小
struct S2
{char c1;char c2;int i;
};
答案:8
题解:
第一成员c1在偏移量为0处。
c2对齐到在自身大小1与默认对齐数8的较小值1的整数倍处,就是在1处。
i对齐到4的倍数处,这里就是4,之前浪费了2个空间
大小是1+1+2+4=8 是成员最大对齐数4的整数倍,所以结构体大小就是8

3)、计算大小
struct S3
{double d;char c;int i;
};
printf("%d\n", sizeof(struct S3));
答案:16
题解:
d在偏移量为0处,往后占8个空间
c要对齐到1的倍数处,本题为9
i要对齐到4的倍数处,本题要对齐到12,之前浪费3个空间,之后往后占4个空间
总大小8+1+3+4=16 是成员最大对齐数8的整数倍,所以结构体大小为16

4)、结构体嵌套
struct S4
{char c1;struct S3 s3;double d;
};
printf("%d\n", sizeof(struct S4));
题解:
c1在偏移量为0处,往后占用一个空间
s3要对齐到某个对齐数的整数倍数处。由于s3是结构体,结构体成员的对齐数是自己的最大对齐数,也就是s3中d的对齐数,所以要对齐到8处。往后占用16个空间
d要对齐到8的整数倍数处,也就是24,往后占用8空间
总大小1+7(浪费空间)+16+8=32,是最大对齐数8的整数倍,所以结构体大小为32
答案:32

二、为什么要有内存对齐
1.移植原因
不是所有的平台都能访问任意空间的数据,所有就要存在一个规定,保证有效移植
2.性能原因
在32位上,硬件在(栈区)访问一次是4字节,存在内存对齐,在访问相同数据时能减少访问次数。以空间换时间。
所以在设计结构体时,尽量让内存小的成员放在一起
就比如题目1和题目2,二者的成员变量相同,但是顺序不同,占用的空间大小不同
所以:
结构体内存对齐的意义就是以空间换时间,设计时,尽量将小成员放一起。
三、修改默认对齐数
#pragma pack( 要修改的数)
修改默认对齐数,一般都是2的n次方
总结
结构体内存对齐是常考点。在进行对齐时,一般总会浪费掉空间,但是却有利于移植,有助于提升效率。内存对齐掌握上述的4条规则,便可游刃有余。
我是凡凡,感谢大家阅读!
相关文章:
详解结构体内存对齐
目录 前言 一、内存大小的计算 1.规则 2.练习 二、为什么要有内存对齐 1.移植原因 2.性能原因 三、修改默认对齐数 总结 前言 本文针对结构体大小的计算进行深度剖析。结构体的大小要遵守内存对齐,在绝大数情况下,会浪费空间。但是有其的价值&…...
指针:程序员的望远镜
指针:程序员的望远镜一、什么是指针1.1 指针的定义1.2 指针和普通变量的区别1.3 指针的作用1.4 指针的优点和缺点二、指针的基本操作2.1 取地址运算符"&"2.2 指针的声明与定义2.3 指针的初始化2.4 指针的解引用2.5 指针的赋值2.6 指针的运算2.7 指针的…...
【python实现学生选课系统】
一、要求: 选课系统 管理员: 创建老师:姓名、性别、年龄、资产 创建课程:课程名称、上课时间、课时费、关联老师 使用pickle保存在文件 学生: 学生:用户名、密码、性别、年龄、选课列表[]、上课记录{课程…...
备受青睐的4D毫米波成像雷达,何以助力高阶自动驾驶落地?
近日,海外媒体曝出特斯拉已向欧洲监管机构提交车辆变更申请,并猜测特斯拉最新的自动驾驶硬件HW4.0或将很快量产上车。据爆料,HW4.0最大的变化是马斯克放弃的毫米波雷达又加了回来,根据国外知名博主Greentheonly的拆解分析…...
3.20算法题(一) LeetCode 合并两个有序数组
题目链接:算法面试题汇总 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 题目描述:给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元…...
QT | 编写一个简单的上位机
QT | 编写一个简单的上位机 时间:2023-03-19 参考: 1.易懂 | 手把手教你编写你的第一个上位机 2.QT中修改窗口的标题和图标 3.图标下载 1.打开QT Creator 2.新建工程 Qt Creator 可以创建多种项目,在最左侧的列表框中单击“Application”&am…...
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(2/5)
目录3、IBL 数学原理3.1、基于微平面理论的 “Cook-Torrance” 模型回顾3.2、 ksk_sks 项与菲涅尔项等价消除3.3、拆分“漫反射项”和“镜面反射项”3、IBL 数学原理 接下来,就让我们正式进入整个 IBL 的数学原理的旅程。请注意,前方高能! …...
嵌入式学习笔记——SysTick(系统滴答)
系统滴答前言SysTick概述SysTick是个啥SysTick结构框图1. 时钟选择2.计数器部分3.中断部分工作一个计数周期(从重装载值减到0)的最大延时时间工作流程SysTick寄存器1.控制和状态寄存器SysTick->CTRL2.重装载值寄存器SysTick->LOAD3.当前值寄存器Sy…...
Linux实操之服务管理
文章目录一、服务(service)管理介绍:service管理指令查看服务名服务的运行级别(runlevel):CentOS7后运行级别说明chkconfig指令介绍一、服务(service)管理介绍: 服务(service)本质就是进程,但是是运行在后台的,通常都会监听某个端口,等待其它…...
基于Java+SpringBoot+vue的毕业生信息招聘平台设计和实现【源码+论文+演示视频+包运行成功】
博主介绍:专注于Java技术领域和毕业项目实战 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟 Java项目精品实战案例(200套) 目录 一、效果演示 二、…...
智能生活垃圾检测与分类系统(UI界面+YOLOv5+训练数据集)
摘要:智能生活垃圾检测与分类系统用于日常生活垃圾的智能监测与分类,通过图片、视频和摄像头识别生活垃圾,对常见的可降解、纸板、玻璃、金属、纸质和塑料等类别垃圾进行检测和计数,以协助垃圾环保分类处理。本文详细介绍基于YOLO…...
建立农村污水处理设施已经成为了当务之急!
在现代社会中,随着城市化进程的加速和人口的增长,选择农村污水处理设备进行污水处理已经成为了一个非常重要的问题。虽然城市中的污水处理设施得到了很好的发展,但是农村地区的污水处理还存在很多问题。 在农村地区,由于缺乏污水…...
【Matlab算法】粒子群算法求解一维线性函数问题(附MATLAB代码)
MATLAB求解一维线性函数问题前言正文函数实现可视化处理可视化结果前言 一维线性函数,也称为一次函数,是指只有一个自变量xxx的函数,且函数表达式可以写成yaxbyaxbyaxb的形式,其中aaa和bbb是常数。具体来说,aaa称为斜…...
【JavaEE】Thread 类及常用方法
一、Thread 类Thread 类我们可以理解为是 java 用于管理线程的一个类,里面封装了操作系统提供的线程管理这一方面的 API (Thread 是优化后的结果), Java 代码创建的每一个线程,可以理解为为 Thread 实例化的对象,Threa…...
C语言数据结构初阶(7)----队列
CSDN的uu们,大家好。这里是C语言数据结构的第七讲。 目标:前路坎坷,披荆斩棘,扶摇直上。 博客主页:姬如祎队列的基础知识队列(queue)是只允许在一端进行插入操作,而在另一端进行删除…...
代码随想录二刷 day01 | 704. 二分查找 27. 移除元素 977. 有序数组的平方
代码随想录二刷day01704. 二分查找27. 移除元素977. 有序数组的平方704. 二分查找 题目链接 做这种题最好现在纸上写一写,如果在大脑中想,可能一会就晕了。 二刷的时候发现了一个新的知识点 即: >>的作用 二分法第二种写法:…...
Linux 终端、进程组、会话、守护进程
文章目录一、终端概念终端概念控制终端二、进程组概念进程组概述进程组相关 API会话会话概念会话相关 API创建会话注意事项守护进程守护进程介绍守护进程模型守护进程参考代码守护进程相关 API参考文章一、终端概念 终端概念 1、终端(Terminal) 终端是…...
你是否有潜质成为谷歌开发者专家?加入 GDE 成长计划,释放潜力!
谷歌开发者专家 (Google Developer Experts,GDE),又称谷歌开发者专家项目,是由一群经验丰富的技术专家、具有社交影响力的开发者和思想领袖组成的全球性社区。通过在各项活动演讲以及各个平台上发布优质内容来积极助力开发者、企业和技术社区…...
安全防御之防火墙篇(二)
目录 1.防火墙如何处理双通道协议? 2.防火墙如何处理NAT? 3.防火墙支持哪些NAT技术,主要应用的场景是什么? 4.当内网PC通过公网域名解析访问内网服务器的时候,会存在什么问题,如何解决?请详细…...
设计必备,5个png免抠素材网站,建议收藏
做设计、PPT都需要用到大量的免抠素材,职场中熟练使用Photoshop的人毕竟是少数,也很少有人愿意花费时间去精细抠图。那这5个免抠素材网站一定要收藏好,可以有效帮你节省时间,提高工作效率。 1、菜鸟图库 https://www.sucai999.co…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...
