18. C语言 结构体内存布局分析与优化
本章目录:
- 结构体的内存布局
- 1. 对齐规则
- 2. 填充与对齐
- 示例分析
- 代码示例
- 输出结果
- 分析
- 1. `debug_size1_t` 结构体
- 2. `debug_size2_t` 结构体
- 如何优化结构体内存布局
- 1. 成员排序优化
- 2. 使用 `#pragma pack` 指令
- 注意事项
- 总结
在C语言中,结构体(struct
)是一个非常常用的复合数据类型,用于将不同类型的数据组合在一起。然而,结构体的内存布局常常让初学者感到困惑,特别是如何理解结构体成员变量的对齐与填充。本文将深入分析C语言中结构体的内存布局,探索成员变量的对齐规则,并通过实例解释如何优化结构体的内存使用。
结构体的内存布局
结构体的内存布局并不是简单的按成员变量的顺序依次分配内存空间。C语言编译器为了提高数据访问的效率,通常会按照某些规则对结构体进行内存对齐和填充。这些规则确保成员变量的地址按照其数据类型大小的倍数进行对齐,从而提高了处理器访问内存的效率。
1. 对齐规则
在大多数平台上(尤其是32位和64位系统),不同类型的数据有不同的对齐要求。比如,char
类型通常对齐到 1 字节,int
类型对齐到 4 字节。因此,编译器会在结构体中插入“空隙”以满足这些对齐要求,从而避免跨越边界访问内存。
2. 填充与对齐
为了确保每个成员变量按正确的边界对齐,编译器可能会在成员变量之间或结构体的末尾添加“填充字节”。这些填充字节不会被程序访问,它们仅仅是为了满足对齐要求。
示例分析
接下来,我们通过具体的例子来详细分析结构体的内存分配情况。
代码示例
#include <stdio.h>typedef struct {unsigned char a; // 1 byteunsigned int b; // 4 bytesunsigned char c; // 1 byte
} debug_size1_t;typedef struct {unsigned char a; // 1 byteunsigned char b; // 1 byteunsigned int c; // 4 bytes
} debug_size2_t;int main(void) {printf("debug_size1_t size=%lu, debug_size2_t size=%lu\r\n", sizeof(debug_size1_t), sizeof(debug_size2_t));return 0;
}
输出结果
debug_size1_t size=12, debug_size2_t size=8
分析
让我们分别分析 debug_size1_t
和 debug_size2_t
两个结构体的内存布局。
1. debug_size1_t
结构体
typedef struct {unsigned char a; // 1 byteunsigned int b; // 4 bytesunsigned char c; // 1 byte
} debug_size1_t;
a
占用 1 字节。b
占用 4 字节,由于unsigned int
通常需要 4 字节对齐,编译器会为b
留出 3 字节的填充空间。c
占用 1 字节。
因此,debug_size1_t
的内存分布如下:
a
:1 字节- 填充:3 字节(为了对齐
b
) b
:4 字节c
:1 字节- 填充:3 字节(为了使结构体的总大小为 4 字节的倍数)
总大小:1 + 3 + 4 + 1 + 3 = 12
字节。
2. debug_size2_t
结构体
typedef struct {unsigned char a; // 1 byteunsigned char b; // 1 byteunsigned int c; // 4 bytes
} debug_size2_t;
a
占用 1 字节。b
占用 1 字节。c
占用 4 字节。
由于 unsigned int
需要 4 字节对齐,编译器会在 b
和 c
之间插入 2 字节的填充空间。
因此,debug_size2_t
的内存分布如下:
a
:1 字节b
:1 字节- 填充:2 字节(为了对齐
c
) c
:4 字节
总大小:1 + 1 + 2 + 4 = 8
字节。
如何优化结构体内存布局
通过上述示例,我们可以看到结构体的内存布局是由成员变量的对齐要求决定的。在某些情况下,内存的浪费是显而易见的,特别是当结构体中有许多小尺寸的成员变量时。为了减少这种内存浪费,我们可以尝试调整结构体成员的顺序,确保成员变量按其大小顺序排列,从而减少填充字节的使用。
1. 成员排序优化
通过重新排列结构体的成员,我们可以减少填充字节的数量。例如,在 debug_size2_t
结构体中,unsigned int
类型的 c
变量应该放在结构体的末尾,以避免在中间产生不必要的填充。
优化后的 debug_size2_t
结构体:
typedef struct {unsigned int c; // 4 bytesunsigned char a; // 1 byteunsigned char b; // 1 byte
} debug_size2_t;
优化后的内存分布:
c
:4 字节a
:1 字节b
:1 字节- 填充:2 字节(为了对齐结构体大小为 4 字节的倍数)
总大小:4 + 1 + 1 + 2 = 8
字节(没有变化,但填充字节的位置得到优化)。
2. 使用 #pragma pack
指令
在某些特定的情况下,如果我们不关心内存对齐规则,或者希望完全控制内存布局,可以使用编译器提供的指令来禁用内存对齐。这通常通过 #pragma pack
实现:
#pragma pack(1)
typedef struct {unsigned char a; // 1 byteunsigned int b; // 4 bytesunsigned char c; // 1 byte
} debug_size1_t;
#pragma pack()
通过这种方式,结构体成员将按照紧凑的方式排列,不再进行对齐,这样可能会降低访问效率,但可以减少内存占用。
注意事项
- 使用
#pragma pack
来强制内存对齐时需要小心,因为它可能导致性能下降,特别是在处理大数据量时。 - 在大多数实际应用中,内存对齐是有益的,因为它能提高访问速度。
总结
C语言中的结构体内存布局是一个复杂但重要的概念。理解结构体的内存对齐与填充规则,有助于我们在开发过程中有效地优化内存使用。通过合理调整结构体成员的顺序,或者在某些情况下使用编译器指令,可以减少内存的浪费,提高程序的性能和效率。希望通过本文的分析,能够帮助读者更好地理解和掌握结构体的内存布局与优化技巧。
相关文章:
18. C语言 结构体内存布局分析与优化
本章目录: 结构体的内存布局1. 对齐规则2. 填充与对齐 示例分析代码示例输出结果分析1. debug_size1_t 结构体2. debug_size2_t 结构体 如何优化结构体内存布局1. 成员排序优化2. 使用 #pragma pack 指令注意事项 总结 在C语言中,结构体(structÿ…...
MyBatisPlus学习笔记
To be continue… 文章目录 介绍快速入门入门案例常用注解常用配置 核心功能条件构造器自定义SQLService接口 介绍 MyBatisPlus只做增强不做改变,引入它不会对现有工程产生影响。只需简单配置,即可快速进行单表CRUD操作,从而节省大量时间。…...
Jetpack工具箱:不只是插件,它是开发灵魂
引言 想象一下,一个 Android 开发者面对堆积如山的需求文档、无穷无尽的 BUG 修复时,突然发现了一款神器——Jetpack!这是一套专为 Android 开发者设计的库和工具集,它就像你的“编程助手”,从架构优化到 UI 管理&…...
2024年博客之星年度评选—创作影响力评审入围名单公布
2024年博客之星活动地址https://www.csdn.net/blogstar2024 TOP 300 榜单排名 用户昵称博客主页 身份 认证 评分 原创 博文 评分 平均 质量分评分 互动数据评分 总分排名三掌柜666三掌柜666-CSDN博客1001002001005001wkd_007wkd_007-CSDN博客1001002001005002栗筝ihttps:/…...
LoadBalancer负载均衡服务调用
LoadBalancer LoadBalancer(负载均衡器)是Spring Cloud中的一个关键组件,用于在微服务架构中实现服务请求的负载均衡。它的主要作用是将客户端的请求分发到多个服务实例上,以提高系统的可用性、性能和容错能力。通过LoadBalancer&…...
《CPython Internals》阅读笔记:p221-p231
《CPython Internals》学习第 12天,p221-p231 总结,总计 11 页。 一、技术总结 无。 二、英语总结(生词:2) 1.at a time idiom. separately(单独地) in the specified groups(一次)。示例: (1) I can only do one thing at …...
【机器学习实战入门】基于深度学习的乳腺癌分类
什么是深度学习? 作为对机器学习的一种深入方法,深度学习受到了人类大脑和其生物神经网络的启发。它包括深层神经网络、递归神经网络、卷积神经网络和深度信念网络等架构,这些架构由多层组成,数据必须通过这些层才能最终产生输出。…...
Golang Gin系列-1:Gin 框架总体概述
本文介绍了Gin框架,探索了它的关键特性,并建立了简单入门的应用程序。在这系列教程里,我们会探索Gin的主要特性,如路由、中间件、数据库集成等,最终能使用Gin框架构建健壮的web应用程序。 总体概述 Gin是Go编程语言的…...
【Python】第二弹---深入理解编程基础:从常量、变量到注释的全面解析
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【MySQL】【Python】 目录 1、常量和表达式 2、变量和类型 2.1、变量是什么 2.2、变量的语法 2.3、变量的类型 2.4、动态类型特…...
RPA编程实践:Electron简介
文章目录 前言使用Electron构建桌面应用程序什么是Electron?为什么选择Electron?如何使用Electron实现上述想法?1. 创建基本的Electron应用2. 配置BrowserWindow3. 定制化你的应用4. 打包与分发 前言 Electron,用官网的话说&…...
svn tag
一般发布版本前,需要在svn上打个tag。步骤如下: 1、空白处右击,选择TortoiseSVN->Branch/tag; 2、填写To path,即tag的路基以及tag命名(一般用版本号来命名);填写tag信息;勾选cr…...
SpringBoot错误码国际化
先看测试效果: 1. 设置中文 2.设置英文 文件结构 1.中文和英文的错误消息配置 package com.ldj.mybatisflex.common;import lombok.Getter;/*** User: ldj* Date: 2025/1/12* Time: 17:50* Description: 异常消息枚举*/ Getter public enum ExceptionEnum {//…...
AAPM:基于大型语言模型代理的资产定价模型,夏普比率提高9.6%
“AAPM: Large Language Model Agent-based Asset Pricing Models” 论文地址:https://arxiv.org/pdf/2409.17266v1 Github地址:https://github.com/chengjunyan1/AAPM 摘要 这篇文章介绍了一种利用LLM代理的资产定价模型(AAPM)…...
LabVIEW桥接传感器配置与数据采集
该LabVIEW程序主要用于配置桥接传感器并进行数据采集,涉及电压激励、桥接电阻、采样设置及错误处理。第一个VI("Auto Cleanup")用于自动清理资源,建议保留以确保系统稳定运行。 以下是对图像中各个组件的详细解释&#…...
《汽车维修技师》是什么级别的期刊?是正规期刊吗?能评职称吗?
问题解答: 问:《汽车维修技师》是不是核心期刊? 答:不是,是知网收录的正规学术期刊。 问:《汽车维修技师》级别? 答:省级。主管单位:北方联合出版传媒(…...
python(25) : 含有大模型生成的公式的文本渲染成图片并生成word文档(支持flask接口调用)
公式样例 渲染前 \[ \sqrt{1904.615384} \approx 43.64 \] 渲染后 安装依赖 pip install matplotlib -i https://mirrors.aliyun.com/pypi/simple/ requestspip install sympy -i https://mirrors.aliyun.com/pypi/simple/ requestspip install python-docx -i https…...
深度学习项目--基于LSTM的火灾预测研究(pytorch实现)
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 前言 LSTM模型一直是一个很经典的模型,这个模型当然也很复杂,一般需要先学习RNN、GRU模型之后再学,GRU、LSTM的模型讲解将…...
云消息队列 Kafka 版 V3 系列荣获信通院“云原生技术创新标杆案例”
2024 年 12 月 24 日,由中国信息通信研究院(以下简称“中国信通院”)主办的“2025 中国信通院深度观察报告会:算力互联网分论坛”,在北京隆重召开。本次论坛以“算力互联网 新质生产力”为主题,全面展示中国…...
centos 安全配置基线
centos 安全配置基线 一、系统防火墙及SE系统1. 系统自带防火墙iptables(Centos6)基础命令查看防火墙设置使用命令查看防火墙设置使用命令清除防火墙设置防火墙策略开放指定的端口屏蔽IP 2. 系统自带防火墙firewalled(Centos7)基础…...
语音技术在播客领域的应用(2)
播客是以语音为主,各种基于AI 的语音技术在播客领域十分重要。 语音转文本 Whisper Whisper 是OpenAI 推出的开源语音辨识工具,可以把音档转成文字,支援超过50 种语言。这款工具是基于68 万小时的训练资料,其中包含11.7 万小时的…...
html的iframe页面给帆软BI发送消息
需求:帆软的网页组件嵌套一个HTML页面,HTML页面要给帆软发消息。 解决方法是:fineReportWindow.duchamp.getWidgetByName("txt1").setValue(666); <!DOCTYPE html> <html lang"en"> <head> <…...
Dart语言的字符串处理
Dart语言的字符串处理 目录 引言字符串的定义与基本特性字符串的创建字符串的操作字符串拼接字符串截取字符串替换字符串分割字符串查询字符串格式化正则表达式在字符串处理中的应用字符串编码与解码示例代码总结 1. 引言 在现代编程中,字符串处理是一个非常重要…...
迅为RK3576开发板Android 多屏显示
迅为iTOP-3576开发板采用瑞芯微RK3576高性能、低功耗的应用处理芯片,集成了4个Cortex-A72和4个Cortex-A53核心,以及独立的NEON协处理器。它适用于ARM PC、边缘计算、个人移动互联网设备及其他多媒体产品。 1.1 Android 多屏同显 iTOP-RK3576 开发板支持…...
基于SpringBoot+Vue旅游管理系统的设计和实现(源码+文档+部署讲解)
个人名片 🔥 源码获取 | 毕设定制| 商务合作:《个人名片》 ⛺️心若有所向往,何惧道阻且长 文章目录 个人名片环境需要技术栈功能介绍功能说明 环境需要 开发语言:Java 框架:springboot JDK版本:JDK1.8 数据库&…...
Banana Pi BPI-RV2 RISC-V路由开发板采用矽昌通信SF2H8898芯片
Banana Pi BPI-RV2 开源网关是⼀款基于矽昌SF2H8898 SoC的设备,1 2.5 G WAN⽹络接⼝、5 个千兆LAN ⽹络接⼝、板载 512MB DDR3 内存 、128 MiB NAND、16 MiB NOR、M.2接⼝,MINI PCIE和USB 2.0接⼝等。 Banana Pi BPI-RV2 开源网关是矽昌和⾹蕉派开源社…...
【0x3D】HCI_Remote_Host_Supported_Features_Notification事件详解
目录 一、事件概述 二、事件格式及参数说明 2.1. HCI_Remote_Host_Supported_Features_Notification事件格式 2.2. BD_ADDR 2.3. Remote_Host_Supported_Features 三、事件作用 3.1. 设备特性沟通与理解 3.2. 功能协商与性能优化 3.3. 设备管理与配置更新 四、应用场…...
【腾讯云】AI驱动TDSQL-C Serveress 数据库技术实战营-如何是从0到1体验电商可视化分析小助手得统计功能,一句话就能输出目标统计图
欢迎来到《小5讲堂》 这是《腾讯云》系列文章,每篇文章将以博主理解的角度展开讲解。 温馨提示:博主能力有限,理解水平有限,若有不对之处望指正! 目录 背景效果图流程图创建数据库 基本信息数据库配置设置密码控制台开…...
Unity-Mirror网络框架-从入门到精通之RigidbodyBenchmark示例
文章目录 前言示例代码逻辑测试结论性能影响因素最后前言 在现代游戏开发中,网络功能日益成为提升游戏体验的关键组成部分。本系列文章将为读者提供对Mirror网络框架的深入了解,涵盖从基础到高级的多个主题。Mirror是一个用于Unity的开源网络框架,专为多人游戏开发设计,它…...
学习记录1
[SUCTF 2019]EasyWeb 直接给了源代码,分析一下 <?php function get_the_flag(){// webadmin will remove your upload file every 20 min!!!! $userdir "upload/tmp_".md5($_SERVER[REMOTE_ADDR]);if(!file_exists($userdir)){mkdir($userdir);}if…...
EWM 供应商退货
目录 1 简介 2 参考内向交货单退货场景 2.1 后台配置 ERP 配置 EWM 配置 2.2 主数据 2.3 业务操作 3 创建 return PO 退货场景 3.1 后台配置 ERP 配置 EWM 配置 3.2 主数据 3.3 业务操作 1 简介 EWM 供应商退货支持 2种方式退货: 1)参考内向交货单退货 2)创建…...
深度学习基础--GRU学习笔记(李沐《动手学习深度学习》)
前言 GRU是RNN模型的升级版,也是LSTM的弱化版,学习GRU也是为了学习LSTM做准备,这一篇文章是学习笔记;RNN:RNN讲解参考:李沐动手学习深度学习;欢迎收藏加关注,本人将会持续更新。 文…...
Linux-C/C++--初探linux应用编程概念
对于大多数首次接触 Linux 应用编程的读者来说,可能对应用编程(也可称为系统编程)这个概念并不 太了解,所以在正式学习 Linux 应用编程之前,笔者有必要向大家介绍这些简单基本的概念,从整体上认识 到应用编…...
计算机基础专业课
后面进一步完善内容! 第一部分:计算机基础知识5% 第一章:计算机概述 第二章:信息表示与编码 第二部分:计算机软硬件基础25% 第三章:计算机系统组成(计算机组成原理) 第四章&am…...
6. 快速掌握抽象类及接口
目录 1. 抽象类1.1 抽象类语法1.2 抽象类特性1.3 抽象类的作用 2. 接口2.1 接口语法2.2 接口的特性 3. 接口案例4. 常用接口4.1 Comparable接口---compareTo()方法4.2 clonable接口---clone方法4.2 深拷贝和浅拷贝 5. Object类5.1 equals()方法5.2 toString()方法5.3 hashCode(…...
P6周:VGG-16算法-Pytorch实现人脸识别
🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 我的环境 语言环境:Python 3.8.12 编译器:jupyter notebook 深度学习环境:torch 1.12.0cu113 一、前期准备 1.设置GPU im…...
GPT-5 传言:一场正在幕后发生的 AI 变革
新的一年,让我们从一个引人入胜的话题开始:如果我告诉你,GPT-5 并非虚构,而是真实存在呢?它不仅真实存在,而且正在你看不见的地方悄然塑造着世界。我的基本假设是:OpenAI 已经秘密开发出 GPT-5&…...
mac配置 iTerm2 使用lrzsz与服务器传输文件
mac配置 1. 安装支持rz和sz命令的lrzsz brew install lrzsz2. 下载iterm2-send-zmodem.sh和iterm2-recv-zmodem.sh两个脚本 # 克隆仓库 git clone https://github.com/aikuyun/iterm2-zmodem ~/iterm2-zmodem# 进入到仓库目录 cd ~/iterm2-zmodem# 设置脚本文件可执行权限 c…...
一、1-2 5G-A通感融合基站产品及开通
1、通感融合定义和场景(阅读) 1.1通感融合定义 1.2通感融合应用场景 2、通感融合架构和原理(较难,理解即可) 2.1 感知方式 2.2 通感融合架构 SF(Sensing Function):核心网感知控制…...
深度学习加速性能分析与Roofline Model
深度学习加速性能分析 动因:由于深度学习加速器普遍采用时分复用(当然随着Graphcore等dataflow类型的芯片除外,他们是空间划分)。此时,硬件资源在不同时刻执行的计算发生变化,很难以单一时刻的计算类型进行硬件设计。所以寻找平均资源利用率就变得更重要方法:针对不同任…...
React 第三方状态管理库相关 -- Redux MobX 篇
一、redux 首先安装依赖: npm install redux react-redux reduxjs/toolkit 示例代码: // src/store/index.js import { configureStore } from reduxjs/toolkit import couterSlice from ./couterSliceconst store configureStore({reducer:{coute…...
“扣子”开发之四:与千帆AppBuilder比较
上一个专题——“扣子”开发——未能落地,开始抱着极大的热情进入,但迅速被稚嫩的架构模型折磨打击,硬着头皮坚持了两周,终究还是感觉不实用不趁手放弃了。今天询问了下豆包,看看还有哪些比较好的AI开发平台࿰…...
C++实现红黑树
红黑树 红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍&…...
Vue3:当v-if和v-for同时使用时产生的问题和解决办法
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/nbci…...
python爬虫入门(理论)
python爬虫 学习网站 一、准备 环境搭建 requests beautifulsoup4 selenium 爬虫架构 URL管理器:管理URL,存储已爬取或待爬取的URL 网页下载器:破解网页,进行下载 网页解析器:对网页的HTML样式、连接的URL等进…...
有效提取激光雷达点云平面点
有效地面点云的提取和平面点的识别是通过一系列步骤实现的。以下是主要步骤: 高度过滤: 首先,根据激光雷达传感器的安装高度,对当前帧扫描得到的点云进行高度过滤,以初步分割出地面点云。假设第 k k k 帧的点云为 { …...
Vulnhub DC-8靶机攻击实战(一)
导语 Vulnhub DC-8靶机教程来了,好久没有更新打靶的教程了,这次我们在来更新一期关于Vulnhub DC-8的打靶训练,如下所示。 安装并且启动靶机 安装并且启动靶机,如下所示。 开始信息采集 进入到Kali中,通过如下的命令来查找到靶机的IP地址。 arp-scan -l根据上面的结…...
基于PHP的校园新闻发布管理
摘要 近年来,随着互联网技术的迅速发展,人们获取新闻的渠道也变得越来越多样化,已经不再拘束于传统的报纸、期刊、杂志等纸质化的方式,而是通过网络满足了人们获得第一手新闻的愿望,这样更加有助于实现新闻的规范化管…...
LabVIEW时域近场天线测试
随着通信技术的飞速发展,特别是在5G及未来通信技术中,天线性能的测试需求日益增加。对于短脉冲天线和宽带天线的时域特性测试,传统的频域测试方法已无法满足其需求。时域测试方法在这些应用中具有明显优势,可以提供更快速和精准的…...
组播PIM-原理介绍+报文分析+配置示例
个人认为,理解报文就理解了协议。通过报文中的字段可以理解协议在交互过程中相关传递的信息,更加便于理解协议。 因此本文将在PIMv2协议报文的基础上进行介绍,以详细介绍组播协议PIM。 这里需要说明的是,以下内容都针对的是ASM&a…...
规避路由冲突
路由冲突是指在网络中存在两个或多个路由器在进行路由选择时出现矛盾,导致网络数据包无法正确传输,影响网络的正常运行。为了规避路由冲突,可以采取以下措施: 一、合理规划IP地址 分配唯一IP:确保每个设备在网络中都有…...