结构体占用内存大小如何确定?-->结构体字节对齐 | C语言
目录
一、什么是结构体
二、为什么需要结构体
三、结构体的字节对齐
3.1、示例1
3.2、示例2
3.3、示例3
3.4、示例4
3.5、示例5
四、结构体字节对齐总结
一、什么是结构体
结构体是将不同类型的数据按照一定的功能需 求进行整体封装,封装的数据类型与大小均可以由用户指定。
结构体定义,如下图1:

图1
二、为什么需要结构体
当需要存储大量重复的信息时,比如存储一个班级学生的信息,肯定包括姓名、学号、性别、年龄、成绩、家庭地址等项。这些项都是具有内在联系的,它们是一个整体,都表示同一个学生的信息。但如果将它们定义成相互独立的变量的话,就无法反映它们的内在联系,如下图2:

图2
如果只是这样写的话,只是定义了一个学生,如果要定义第二个学生就要再写一遍。这样不仅麻烦,而且很容易混淆。要是能定义一个变量,而且这个变量正好包含这六个项,即将它们合并成一个整体的话就好了。结构体就是为了解决这个问题而产生的。
三、结构体的字节对齐
现在来探讨一个问题,结构体的大小是如何划分的呢?
3.1、示例1
有这样一个程序,结构占用内存大小按理来说应该是,char占1个字节,int占4个字节,1+4=5,结构体占用内存大小应该是5个字节才对。
#include <stdio.h>struct STUDENT{char a;int b;}data;int main()
{printf("a的地址为:%p,b的地址为:%p\n", &data.a, &data.b); //%p是取地址符printf("结构体总大小为:%d\n", sizeof(data));return 0;
}
以上程序输出结果如下图3所示:
图3
内存分配图下图4:

图4
分析:
事实上结构体大小是8个字节,b占4字节我们能理解,但a是char型,char型不是占1字节吗,这里为什么占4字节?其实不是它占了4字节,它占的还是1字节,只不过结构体中有一个字节对齐的概念。
那么到底是怎么存储的呢?
就是按字节对齐的方式存储的!即以结构体成员中占内存最多的数据类型所占的字节数为标准,所有的成员在分配内存时都要与这个长度对齐。
以上面这个程序为例,结构体变量data的成员中占内存最多的数据类型是int型,其占4字节的内存空间,那么所有成员在分配内存时都要与4字节的长度对齐。也就是说,虽然char只占1字节,但是为了与4字节的长度对齐,它后面的3字节都会空着。
3.2、示例2
按上面的结论,最大的是int占4个字节,那么按4字节对齐,大小应该是4+4+4=12;
#include <stdio.h>struct STUDENT{char a;cahr c;int b;}data;int main()
{printf("a的地址为:%p,b的地址为:%p,c的地址为:%p\n", &data.a, &data.b, &data.c);printf("结构体总大小为:%d\n", sizeof(data));return 0;
}
结果如下图5:

图5
但大小实际上并没有变化,内存分配为下图6所示:

图6
分析:
在分配了a的内存后,c希望和a近邻,并且因为内存对齐a申请了4个字节,在a相邻的位置可以存放,所以c与a共同占用一个4字节内存。
3.3、示例3
首先最长的数据类型占4字节,所以是以4字节对齐。1+1+1+1+4+4=12
#include <stdio.h>struct STUDENT{char a;char c;char d;char f;char e;int b;}data;int main()
{printf("a的地址为:%p,b的地址为:%p,c的地址为:%p,d的地址为:%p,f的地址为:%p,e的地址为:%p\n", &data.a, &data.b, &data.c, &data.d, &data.f, &data.e);printf("结构体总大小为:%d\n", sizeof(data));return 0;
}
输出结果如下图7:

图7
即该结构体变量分配内存时如下图8:

图8
分析:
首先最长的数据类型占4字节,所以是以4对齐。a占1字节,b接在a后面占1字节,c接在b后面占1字节,d接在c后面占1字节,此时满4字节了,e再来就要另起一行。f想紧接着e后面分配,但e后面还剩3字节,小于int类型的4字节,所以f另起一行。
3.4、示例4
首先最长的数据类型占4字节,所以是以4字节对齐。4+4+4=12。
#include <stdio.h>struct STUDENT{char a;int c;char b;}data;int main()
{printf("a的地址为:%p,b的地址为:%p,c的地址为:%p\n", &data.a, &data.b, &data.c);printf("结构体总大小为:%d\n", sizeof(data));return 0;
}
输出结果如下图9:

图9
内存分配如下图10:

图10
分析:
首先最长的数据类型占4字节,所以是以4对齐。a占1字节,c希望与a近邻,但3字节不足以存放int,故重新再起一行,所以a占4字节。b也希望与a近邻,但a空间不足以存放b,故b也重新起一行占4个字节。
3.5、示例5
首先最长的数据类型占4字节,所以是以4字节对齐。但出现了数组,大小应该怎样计算呢?
#include <stdio.h>struct STUDENT
{char name[3];int age;char sex;char score;
}data;int main()
{printf("%p,%p,%p,%p,%p,%p\n", &data.name[0], &data.name[1], &data.name[2], &data.age, &data.sex, &data.score);printf("结构体总大小为:%d\n", sizeof(data));return 0;
}
输出结果如下图11:

图11
分析:
出现了数组,数组可以看做多个char类型,依然是占1字节,所以内存大小为:4+4+4=12。
四、结构体字节对齐总结
概念总结:
1)可以知道,同样的数据类型,只不过交换了一下位置,结构体变量data所占的内存空间就由8字节变成12字节,多了4字节。这就告诉我们,在声明结构体类型时,各类型成员的前后位置会对该结构体类型定义的结构体变量所占的字节数产生影响;
2)没有规律的定义会增加系统给结构体变量分配的字节数,降低内存分配的效率。但这种影响对操作系统来说几乎是可以忽略不计的!所以我们在写程序的时候,如果有心的话,声明结构体类型时就按成员类型所占字节数从小到大写,或从大到小写;
3)但是如果没有按规律书写的话也不要紧,声明结构体类型时并非一定要从小到大声明,只是为了说明结构体字节对齐这个概念。
使用总结:
1)按占用最大的字节对齐;
2)占用内存可以共用(前提是足以同时保存);
3)不足以存放时,会出现申请一个内存空间;
4)合理书写顺序可以节省CPU资源,当量足够大时,有可能会影响系统运行效率。
如果在单片机使用RTOS,RTOS管理的内存空间固定,但因为结构体申请了很多内存,在使用时,有可能因为内存不足而产生不必要的错误。
相关文章:
结构体占用内存大小如何确定?-->结构体字节对齐 | C语言
目录 一、什么是结构体 二、为什么需要结构体 三、结构体的字节对齐 3.1、示例1 3.2、示例2 3.3、示例3 3.4、示例4 3.5、示例5 四、结构体字节对齐总结 一、什么是结构体 结构体是将不同类型的数据按照一定的功能需 求进行整体封装,封装的数据类型与大小均…...
Vue和Uniapp:优缺点比较
Vue和Uniapp是两个流行的前端框架,都是用于开发跨平台应用程序的工具。虽然两者都有很多相似之处,但它们也有一些不同之处,这些不同之处可以影响你的选择。下面将对Vue和Uniapp的优缺点进行比较和分析,以帮助你做出更明智的决策。…...
AMBA-AXI(二)AXI的序,保序与乱序
💡Note:本文是根据AXI协议IHI0022F_b_amba_axi_protocol_spec.pdf(issue F)整理的。主要是分享AXI3.0和4.0部分。如果内容有问题请大家在评论区中指出,有补充或者疑问也可以发在评论区,互相学习ὤ…...
APIs and Open Interface--非工单领、发料(含调拨)
表名 MTL_TRANSACTIONS_INTERFACEMTL_TRANSACTION_LOTS_INTERFACE序列 MTL_MATERIAL_TRANSACTIONS_S.NEXTVALAPIs INV_TXN_MANAGER_PUB.PROCESS_TRANSACTIONS案例 杂发/杂收(代码)Declare v_user_id number : fnd_global.user_id; v_login_id number …...
互联网医院系统软件开发|互联网医院管理系统开发的好处
互联网医院一直是现在的热门行业,很多的医院已经开发了互联网医院,并且已经在良好的运行中,而有一些医院和企业正在开发中,或者打算开发互联网医院系统,其实这些企业和医院还是很有远见的,因为他们知道并了…...
2.单例模式
基本概念 单例模式:保证一个类只有一个实例,并提供一个访问该实例的全局访问点 常见应用场景 读取配置文件的类一般设计为单例模式网站计数器应用程序的日志应用,因为共享日志文件一直处于打开状态,只能有一个实例去操作Spring…...
【保姆级】Java后端查询数据库结果导出xlsx文件+打印xlsx表格
目录前言一、需求一:数据库查询的数据导出成Excel表格1.1 Vue前端实现导出按钮点击事件1.2 后端根据数据库查询结果生成xlsx文件二、需求二:对生成的xlsx文件调用打印机打印2.1 Vue前端实现按钮事件2.2 后端实现打印前言 最近在弄一个需求,需…...
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
文章目录1 JDBC(Java Database Connectivity)1.1 什么是 JDBC?1.2 JDBC 核心思想2 JDBC开发步骤【重点】2.0 环境准备2.1 注册数据库驱动2.2 获取数据库的连接2.3 获取数据库操作对象Statement2.4 通过Statement对象执行SQL语句2.5 处理返回结…...
vue3生命周期
一、Vue3中的生命周期 1、setup() : 开始创建组件之前,在 beforeCreate 和 created 之前执行,创建的是 data 和 method 2、onBeforeMount() : 组件挂载到节点上之前执行的函数; 3、onMounted() : 组件挂载完成后执行的函数; 4、…...
Python学习笔记10:开箱即用
开箱即用 模块 python系统路径 import sys, pprint pprint.pprint(sys.path) [,D:\\Program Files\\Python\\Lib\\idlelib,D:\\Program Files\\Python\\python310.zip,D:\\Program Files\\Python\\DLLs,D:\\Program Files\\Python\\lib,D:\\Program Files\\Python,D:\\Progr…...
详解JAVA反射
目录 1.概述 2.获取Class对象 3.API 3.1.实例化对象 3.2.方法 3.3.属性 1.概述 反射,JAVA提供的一种在运行时获取类的信息并动态操作类的能力。JAVA反射允许我们在运行时获取类的属性、方法、构造函数等信息,并能够动态地操作它们。 2.获取Class…...
在nestjs中进行typeorm cli迁移(migration)的配置
在nestjs中进行typeorm cli迁移(migration)的配置 在学习nestjs过程中发现typeorm的迁移配置十分麻烦,似乎许多方法都是旧版本的配置,无法直接使用. 花了挺长时间总算解决了这个配置问题. db.config.ts 先创建db.config.ts, 该文件export了两个对象,其…...
前端工程构建问题汇总
1.less less-loader安装失败问题 npm install less-loader --save --legacy-peer-deps 加上–legacy-peer-deps就可以了 在NPM v7中,现在默认安装peerDependencies,这会导致版本冲突,从而中断安装过程。 –legacy-peer-deps标志是在v7中引…...
某马程序员NodeJS速学笔记
文章目录前言一、什么是Node.js?二、fs文件系统模块三、Http模块四、模块化五、开发属于自己的包模块加载机制六、Express1.初识ExpressGET/POSTnodemon2.路由模块化3.中间件中间件分类自定义中间件4. 跨域问题七、Mysql模块安装与配置基本使用Web开发模式Session认证JWT八、m…...
SpringMVC DispatcherServlet源码(6) 完结 静态资源原理
阅读源码,分析静态资源处理器相关组件: 使用SimpleUrlHandlerMapping管理url -> 处理器映射关系spring mvc使用WebMvcConfigurationSupport注入SimpleUrlHandlerMapping组件DelegatingWebMvcConfiguration可以使用WebMvcConfigurer的配置静态资源url…...
2023年全国最新会计专业技术资格精选真题及答案9
百分百题库提供会计专业技术资格考试试题、会计考试预测题、会计专业技术资格考试真题、会计证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 四、材料题 1.某企业为增值税一般纳税人,2019年12月初“应付职工薪酬…...
Web3中文|把Web3装进口袋,Solana手机Saga有何魔力?
2月23日,Solana Web3手机Saga发布新的消息,将推出NFT铸造应用程序Minty Fresh。在Minty Fresh,用户仅需轻点并完成拍摄,就可以直接在手机中进行NFT铸造,并在几秒钟内将其转换为链上NFT,NFT还可以发布在 Ins…...
【配电网优化】基于串行和并行ADMM算法的配电网优化研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
数据结构初阶 -- 顺序表
数据结构初阶 链表的讲解 目录 一. 线性表 1.1 定义 1.2 特点 二. 顺序表 2.1 定义 2.2 代码 2.3 功能需求 2.4 静态顺序表的特点以及缺点 2.5 动态的顺序表 2.6 动态顺序表接口的实现 三. 代码 头文件 主文件 一. 线性表 1.1 定义 线性表(linear li…...
uniapp:3分钟搞定在线推送uni.createPushMessage,uni.onPushMessage
安卓端 在线推送功能演示: 1、dcloud后台申请开通uniPush dcloud后台 (1):找到我的应用 (2):点进去后,各平台信息,点击新增 (3):填…...
Nornir网络自动化监控插件:集成Sentry实现异常告警与上下文追踪
1. 项目概述:一个为Nornir网络自动化框架量身定制的告警与监控插件 如果你和我一样,长期使用Nornir框架来管理成百上千的网络设备,那你一定遇到过这样的场景:一个精心编写的自动化任务在测试环境跑得飞快,一旦放到生产…...
服务器上5分钟搞定:用wget直接下载并配置mongodump备份工具(Linux实战)
服务器极速部署指南:5分钟完成mongodump备份工具配置 在Linux服务器运维中,时间就是效率。想象一下这样的场景:凌晨三点收到数据库告警,你需要立即建立备份机制,但传统的"下载-上传-配置"流程至少需要15分钟…...
STL到STEP格式转换:技术选型与实施指南
STL到STEP格式转换:技术选型与实施指南 【免费下载链接】stltostp Convert stl files to STEP brep files 项目地址: https://gitcode.com/gh_mirrors/st/stltostp 在制造业数字化转型的背景下,3D数据格式互操作性已成为工程团队面临的核心挑战。…...
NVIDIA Profile Inspector终极指南:解锁显卡隐藏性能的700+高级设置
NVIDIA Profile Inspector终极指南:解锁显卡隐藏性能的700高级设置 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 作为一款开源显卡配置工具,NVIDIA Profile Inspector提供了直…...
SciPy 图结构
在 SciPy 中,图结构(Graph) 的处理主要依赖于 scipy.sparse.csgraph 模块。该模块专门用于处理稀疏矩阵表示的图(邻接矩阵或拉普拉斯矩阵),提供了一系列高效的图算法。 注意:SciPy 的图功能侧重…...
pyecharts本地静态资源部署终极指南:告别网络依赖,实现高速可视化
pyecharts本地静态资源部署终极指南:告别网络依赖,实现高速可视化 【免费下载链接】pyecharts-assets 🗂 All assets in pyecharts 项目地址: https://gitcode.com/gh_mirrors/py/pyecharts-assets pyecharts-assets 是一个专为pyecha…...
3步完成NCM转MP3:网易云音乐格式转换终极指南
3步完成NCM转MP3:网易云音乐格式转换终极指南 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾为网易云音乐下载的NCM格式文件无法在其他设备播放而烦恼?这款开源NCMDump工具为你提供完美的解决方案&a…...
3分钟搞定AI短视频:零门槛创作神器完全指南
3分钟搞定AI短视频:零门槛创作神器完全指南 【免费下载链接】MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频 Generate short videos with one click using AI LLM. 项目地址: https://gitcode.com/GitHub_Trending/mo/MoneyPrinterTurbo 还…...
【Unity进阶实战】将PC端EXE打包与压缩一体化:从项目设置到单文件发布
1. Unity项目打包前的关键设置 第一次用Unity打包PC端应用时,我踩过不少坑。记得有个项目打包后死活运行不起来,折腾半天才发现是场景没正确添加。所以打包前的准备工作特别重要,咱们一步步来。 打开Build Settings窗口(File >…...
Mulch:轻量级声明式Docker编排工具,简化单机应用部署与管理
1. 项目概述与核心价值最近在折腾一个自托管的小型服务器,主要用来跑一些个人项目、家庭媒体服务和自动化脚本。随着服务越装越多,一个老问题又浮出水面:如何高效、安全地管理这些应用?传统的做法要么是手动安装配置,过…...
