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

C语言结构体中的内存对齐

C语言结构体内存对齐

在C语言编程中,结构体是一种非常重要的数据类型,它允许我们将不同类型的数据组合在一起。然而,当涉及到结构体在内存中的存储时,有一个关键的概念——内存对齐,这往往容易被忽视,但却对程序的性能和内存使用有着重要影响。

一、结构体大小计算的“理论”与“实际”差异

首先,我们可能会想当然地认为,结构体的大小就是其所有成员大小的简单相加。比如,有这样一个结构体:

struct studentinfo
{char name[128];int *p;short b;int c;unsigned int age;char sex[20];
};

理论上计算各成员大小之和:128 + 8 + 2 + 4 + 4 + 20 = 166字节(在64位系统中,指针int *p占8字节)。但实际通过sizeof运算符计算时,在64位系统下得到的结果是168字节,和理论值存在偏差。这是为什么呢?

二、内存对齐的原因

这就涉及到内存对齐了。计算机为了提高CPU的寻址效率,在存储数据时会进行内存对齐。一般来说,嵌入式系统多采用32位系统,CPU的地址总线是32位,为了提升CPU的工作效率,寻址通常以4字节为单位。当数据宽度不足4字节时,系统会默认提供4字节内存方便CPU寻址,这种方式就是字节对齐。

我们可以通过示意图来理解:
image

  • 地址未对齐的情形:CPU读取数据时可能需要多次读取,比如要读取一段数据,可能需要读取3次才能获取完整数据。
  • 地址已对齐的情形:CPU可以更少次数地读取到完整数据,比如2次就可以,大大提高了效率。

所以,计算结构体大小时考虑内存对齐是典型的“以空间换时间”的案例,用少量的内存空间浪费换取CPU寻址效率的提升。

三、结构体大小计算示例

来看一个具体的题目:

//假设是32bit系统
#include <stdio.h>
struct A{int i;char j;char * ptr;long Array[100];char b[2];char * c;
};
int main()
{printf("%d\n", sizeof(struct A));return 0;
}

在32位系统中,各成员的对齐数(自身大小)如下:

  • int i:4字节(对齐数4)
  • char j:1字节(对齐数1)
  • char *ptr:4字节(指针在32位系统中占4字节,对齐数4)
  • long Array[100]:每个long占4字节(对齐数4),数组整体占4×100=400字节
  • char b[2]:2字节(对齐数1,数组整体占2字节)
  • char *c:4字节(对齐数4)

分步计算过程:

  1. int i
    从地址0开始存储,占用4字节(地址0~3)。

  2. char j
    对齐数为1,可紧跟在i之后,从地址4开始,占用1字节(地址4)。

  3. char *ptr
    对齐数为4,需从4的整数倍地址开始。当前已用地址到4,下一个4的整数倍地址是8,因此从地址8开始存储,占用4字节(地址8~11)。
    注意:地址5~7为填充空间(3字节,因j只占1字节,需补齐到4的整数倍才能存放ptr)。

  4. long Array[100]
    对齐数为4,当前已用地址到11,下一个4的整数倍地址是12,从地址12开始存储,占用400字节(地址12~411)。

  5. char b[2]
    对齐数为1,紧跟Array之后,从地址412开始,占用2字节(地址412~413)。

  6. char *c
    对齐数为4,需从4的整数倍地址开始。当前已用地址到413,下一个4的整数倍地址是416,从地址416开始存储,占用4字节(地址416~419)。
    注意:地址414~415为填充空间(2字节)。

总大小计算:

所有成员存储结束后,最后一个成员c占用到地址419,此时已用空间为420字节(0~419共420字节)。
由于结构体最大对齐数为4(所有成员的对齐数均不超过4),420是4的整数倍(420÷4=105),满足整体对齐要求。

因此,结构体struct A的大小为420字节

四、按需分配内存:取消内存对齐

在某些嵌入式产品中,内存大小极其有限,我们希望内核在分配内存单元时采用“按需分配”的原则,也就是取消内存对齐。这时候可以使用C语言标准的预处理指令#pragma pack(n),其中n的值可以是1、2、4、8等,用于进行字节对齐以及取消字节对齐。
image

例如:

#pragma pack(1)  // 取消字节对齐 64bit系统下
struct studentinfo
{char name[10];int *p;short b;char c;int a;unsigned int age;
};
#pragma pack()  // 恢复字节对齐

在取消字节对齐后,计算结构体大小就是各成员大小的简单相加,比如上述结构体计算得到的大小是29字节,相比有内存对齐时的大小,节省了内存空间,不过这是以牺牲CPU寻址效率为代价的。

五、总结

内存对齐是C语言中一个重要的概念,它平衡了内存空间和CPU寻址效率。在大多数情况下,默认的内存对齐能够很好地提升程序性能。但在内存资源极度紧张的场景下,我们可以通过#pragma pack指令来取消内存对齐,实现“按需分配”内存。

相关文章:

C语言结构体中的内存对齐

C语言结构体内存对齐 在C语言编程中,结构体是一种非常重要的数据类型,它允许我们将不同类型的数据组合在一起。然而,当涉及到结构体在内存中的存储时,有一个关键的概念——内存对齐,这往往容易被忽视,但却对程序的性能和内存使用有着重要影响。 一、结构体大小计算的“理…...

该练习 DP 了!

区间DP 洛谷P3147Problem 定义 \(f[i][j]\) 存储从左端点 \(j\) 开始,能合并出 \(i\) 的右端点位置,将其设为 \(k\) 。 下面我们推转移方程。从题意可以看出,两个相邻的 \(i-1\) 能够合并出 \(i\) 。那么在 \(f[i][j]\) 后所对应的就是 \(f[i][k]\),这两个 \(i\)合并能够得…...

本周计划

周三: 上午 8:00~10:30 新领军 10:30~11:30 ZR NOIPD3 T4 下午模拟赛 晚上新领军习题课两节 周四: 上午 8:00~11:30 补好题分享 2 道 下午 2:00~4:30 补模拟赛 晚上 6:30~8:00 补模拟赛或好题分享 周五 上午 8:00~11:30 补好题分享 2 道 下午 2:00~5:30 准备下个周好题分享,…...

PPT文件太大?一招「无损」压缩图片,秒变传输小能手!

本文介绍的方法基于「PPT百科网」提供的在线分析工具,可智能评估并指导压缩过程,确保最佳效果。 PPT文件体积暴涨,99%的根源在于内部图片分辨率过高。直接使用PowerPoint自带的“压缩图片”功能虽然简单,但如同一刀切,可能导致在其他设备上播放时图片模糊,风险不可控。 「…...

9月16模拟赛

题目很难 主要是没有找对策略 就是没有及时去想部分分 怎么说呢 实力太弱 其实部分分拿完也会有个不错的成绩 无所谓 csp rp++!...

C++ 单例 Meyers Singleton(迈耶斯单例)

Meyers Singleton(迈耶斯单例)是 C++ 中实现单例模式的一种简洁高效的方法,由 C++ 专家 Scott Meyers 提出。其核心原理是利用局部静态变量的初始化特性保证单例的唯一性和线程安全性(C++11 及以后标准)。 1、核心原理局部静态变量的初始化特性 在 C++ 中,函数内的局部静…...

EF Core 与 MySQL:查询优化详解

EF Core 与 MySQL:查询优化详解 1. 使用 AsNoTracking 提高查询性能 基本用法// 常规查询(会跟踪实体变更) var products = context.Products.Where(p => p.Price > 100).ToList();// 使用 AsNoTracking(不跟踪实体变更,性能更好) var products = context.Product…...

短视频营销运营资深导师张伽赫,东莞绳木传媒创始人

东莞绳木传媒创始人张伽赫,短视频营销运营领域的资深导师。凭借其对行业趋势的敏锐洞察与实战经验,已成为企业数字化转型中短视频营销领域的标杆人物。他深耕短视频赛道多年,不仅构建了从账号定位、内容创作到流量转化的完整方法论,更通过绳木传媒为企业提供“AI+短视频”全…...

20250913

T4。T1 查询被包含的区间 将区间视为平面上的点 \((l, r)\),则每次询问的合法范围容易表示,是一个三角形。可以通过两步容斥转化为一个一维偏序和三个二维偏序。直接做就好了。代码 #include <iostream> #include <algorithm> #define lowbit(x) ((x) & (-(…...

9.13日总结

整体总结: 1.在自己的大样例出问题时要及时找老师考大样例 不要对着不对的大样例虚空调试 2.在考场上要自己造大样例 要造极限数据 这样可以防止数组越界 3.在数据不超过5e6的情况下 单log都是可以过的 只要极限数据跑的不是很慢就不用担心常数问题 4.在考场上要留一个小时以上…...

哇哇哇下雨了!——2025 . 9 . 16

哇哇哇下雨了! 感觉我从小就不喜欢晴天,反而钟爱雨天,其实每次下雨我心里就在想“哇哇哇又下雨了”。 可能跟打小的性格有关,也可能跟那个人有关。 当时我写了好多关于雨的小诗,无论是给她的还是给我自己的,内容也想不起来几句了。那会儿虽然每天的生活是无味的严苛的,但…...

奇思妙想(胡思乱想)

前言: 作为一个想象力 丰富 夸张的人,总有一些奇思怪想,浅浅记录一下呀~~ 可能会很奇怪以及不符合实际,毕竟是想象的【逃】 正文:圈养的猪会不会觉得人类的是自己的奴隶(因为一直好吃好喝的供着它们) 睡觉会不会就是脑电波以第一视角或第三视角的方式观察到平行宇宙的自…...

AI Compass前沿速览:GPT-5-Codex 、宇树科技世界模型、InfiniteTalk美团数字人、ROMA多智能体框架、混元3D 3.0

AI Compass前沿速览:GPT-5-Codex 、宇树科技世界模型、InfiniteTalk美团数字人、ROMA多智能体框架、混元3D 3.0AI Compass前沿速览:GPT-5-Codex 、宇树科技世界模型、InfiniteTalk美团数字人、ROMA多智能体框架、混元3D 3.0 AI-Compass 致力于构建最全面、最实用、最前沿的AI…...

C++中set与map的自定义排序方法详解

在C++标准模板库(STL)中,set和map是两种常用的关联容器,它们默认按照键的升序进行排序。但在实际开发中,我们经常需要根据特定需求对元素进行自定义排序。本文将详细介绍如何为set和map实现自定义排序。 默认排序行为 在深入了解自定义排序之前,我们先看一下set和map的默认…...

id

卷姬神经瓦特 2025.09.16本文来自博客园,作者:transformert,转载请注明原文链接:https://www.cnblogs.com/ac-network/p/19095883...

【汇总】Qt常用模块头文件

一、变量、命令、参数排序 项目.pro文件 模块导入 include 文件 中文说明 备注、示例ABCDEFGHIJKLM#include <QMessageBox> 信息提示窗口QMessageBox::about(this, "关于",“关于说明”);NOPQRSQT += serialport #include <QSerialPort> 串口控制类#inc…...

Advanced Algorithm —— Hashing and Sketching

Birthday Problem \(m\) 个人,\(n\) 天,没有两个人生日相同的概率为: \[\displaystyle{ \begin{align*} \Pr[\mathcal{E}]=\left(1-\frac{1}{n}\right)\cdot \left(1-\frac{2}{n}\right)\cdots \left(1-\frac{m-1}{n}\right) &= \prod_{k=1}^{m-1}\left(1-\frac{k}{n}\r…...

CF2136 Codeforces Round 1046 (Div. 2) 补题

题目标签B笛卡尔树的应用C有思维难度的 dp / 递推D交互题 利用曼哈顿距离反过来解坐标:二元线性方程组 考虑“问最值/极限情况”E二分图,边双连通分量 两条路径 -> 环 异或运算的性质 (见题解)题解:E. By the Assignment观察1:对于本题,每个边双连通分量内部的点权可…...

【IEEE出版、EI检索稳定】第四届云计算、大数据应用与软件工程国际学术会议(CBASE 2025)

第四届云计算、大数据应用与软件工程国际学术会议(CBASE 2025) 2025 4th International Conference on Cloud Computing, Big Data Application and Software Engineering 在这里看会议官网详情 2025年10月24-26日丨中国-成都(线上同步举办) 截稿日期:看官网 检索类型:IE…...

缺省源

自用,你不见得会用。 快读:点击查看代码 #define getc() getchar_unlocked() #define putc(a) putchar_unlocked(a) #define en_ putc(\n) #define e_ putc( )template<class T> inline T in() { T n = 0; char p = getc();while (p < -) p = getc();bool f = p == …...

97. 交错字符串

题目链接:97. 交错字符串 - 力扣(LeetCode)‘解析:二维dp dp[i][j]代表s1前i个和s2前j个是否能组成s3的i+j个 状态转移方程就很简单了, 但这一题要求空间限制,可以观察到dp其实只记录一维就可以,因为用到了i-1或者j-1class Solution { public:bool isInterleave(string …...

MODint(自动取模)

主要来自here,我就只是补充了点东西,修改了一点东西,改了点 re 判断。 建议和我的快读一同使用,兼容的。 in,out兼容,不过建议in(a.val),快一些。同理,建议out(a.val) 不行的话也有流输入输出的兼容。 除法是 \(O(\log mod)\) 的,嫌慢可以自行修改 inv() 函数内容。 t…...

BFD实验

动态bfd+OSPF: bfd q ospf 1 bfd all-interfaces enable net .... net .......

2025.9.16——卷1阅读程序1、2

阅读程序2 vector容量与大小 容量表示在不申请内存的情况下vector还可以添加多少元素,通常超过限制之后容量会增加>=1,具体看算法实现 大小表示vector中有多少元素 .assign(n,val) 将vector的内容替换为n个val值的元素...

25/9/15(补)

来的比较晚,把ABC题改了,随机跳了一道贪心+数学题,学习了一下题解思路。然后做了下2020csps单选,错了2道。不知道今年没有小学生s分数线会不会巨高,后面几天就练练第一轮。...

[Paper Reading] DINOv3

目录DINOv3TL;DRMethodDataArchitectureLearning ObjectiveGram Anchoring ObjectiveLeveraging Higher-Resolution Featurespost-hoc strategiesExperiment相关链接 DINOv3 link 时间:25.08 单位:Meta 相关领域:Self Supervised Learning 作者相关工作: 被引次数:7 项目主…...

25/9/16

作业比较多,来的时候就剩25分钟了,于是补了一下博客,复习了一下之前写的题。然后又研究了一下昨天的P11205(贪心+数学),稍微参悟到了一些。...

JavaDay5

增强for循环 Java增强for循环语法格式如下: for(声明语句:表达式) {//代码句子 }声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在环语句块,其值与此时数组元素的值相等。 表达式:表达式是要访问的数组名,或者是返回值为数组的方法 packag…...

揭秘Mobile Me数据挖掘:从WebDAV探测到隐藏文件发现

本文详细分析了Mobile Me服务的公开文件访问机制,通过WebDAV协议和XML解析技术实现目录遍历,发现用户代理字符串影响隐藏文件显示,并开发了自动化探测工具Me Finder进行数据收集。我最近发布了Bucket Finder脚本,Darren在Hak5节目中进行了专题报道。有反馈指出Mobile Me采用…...

25/9/14(补)

下午: 随机跳题做了p2926 就是一个每个数字为a[i]的环,对于每个a[i]统计a[i]是aj的因数的a[j]个数。 做法:首先是否是环对答案无影响,因为每个数都要走一遍,所以开一个桶b,记录每个数字的出现次数,外层1-1000000枚举i,判断b[i]是否有值,如果有内层1-1000000/i枚举判断b…...

【IEEE出版、往届会后4个月EI检索】第二届计算机视觉、图像处理与计算摄影国际学术会议(CVIP 2025)

第二届计算机视觉、图像处理与计算摄影国际学术会议(CVIP 2025) 2025 2nd International Conference on Computer Vision, Image Processing and Computational Photography *IEEE出版 | 往届会后4个月EI检索,非常稳定!收录范围广 重要信息 在这里看会议官网详情 时间地点:…...

VSCode + Python 开发踩坑:虚拟环境不在项目根目录导致包无法识别该怎么办

最近在学习Dify ,尝试自己使用源码启动项目并进行二次开发。 我按照Dify的官方文档说明使用uv在项目的api目录下安装了Python虚拟环境,但是在VSCode右下角的Python解释器选择中却无法像conda管理的虚拟环境一样直接找到并选中,需要手动选择解释器存在,而且我在手动设置之后…...

洛谷 P10936 导弹防御塔 题解

题目描述请移步 https://www.luogu.com.cn/problem/P10936题目简述有n个防御塔,每个防御塔都有充足的导弹 导弹需要一定时间发出,又需要一定时间冷却 导弹有确定的速度,发出后会沿最短路径攻击任意一个入侵者 有m个入侵者,给定防御塔和入侵者的坐标,求至少多久才能击退所有…...

Python爬虫实战:研究Pandas,构建地理信息资料采集和分析便捷的系统

Python爬虫实战:研究Pandas,构建地理信息资料采集和分析便捷的系统pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier Ne…...

初赛复习

重要知识点 存储单位卡特兰数 以下是一些卡特兰数 \(C_n\) 的应用:二叉树计数\(n\) 个结点的不同形态的二叉树的数量是卡特兰数 \(C_n\)。括号匹配\(n\) 对括号的有效组合数。栈操作序列(出栈顺序)\(n\) 个元素的出栈顺序数。凸多边形的三角划分\(n + 2\) 条边的凸多边形划分…...

用户帐户控制(UAC)

您拥有标准用户的用户名和密码。可在 中查看lusrmgr.msc 。...

fg/bg/jobs/kill命令--linux

[转载](https://www.cnblogs.com/machangwei-8/p/10391440.html) 目录一、命令详解二、进程的终止三、进程的挂起(暂停) 基础命令学习目录首页原文链接:http://www.cnblogs.com/chjbbs/p/6307333.html linux提供的fg和bg命令,可以让我们轻松调度正在运行的任务假如你发现…...

【OC】单例模式 - 教程

【OC】单例模式 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-size: 1…...

ios电脑系统和windows系统

iOS电脑系统与Windows系统的对比与选择指南 一、引言 随着科技的快速发展,个人计算机已经成为了我们日常生活中不可或缺的一部分。操作系统作为连接硬件与应用程序之间的桥梁,其重要性不言而喻。在众多操作系统中,iOS(实际上,这里应当指的是macOS,因为iOS是苹果公司为移动…...

HCIP-VRRP

...

JSON Schema 校验是什么?面试时怎么说?

JSON Schema 校验,其实就是 对接口返回的数据结构做自动化校验,确保它符合预期格式。 比如下单接口返回的数据是这样的: { "orderId": 12345, "status": "paid", "amount": 58.5, "items": [ { "productId": 1…...

【征文启动】IvorySQL PostgreSQL 迁移实战经验征集:分享你的技术沉淀,赢取专属好礼!

在数据库技术选型与迭代的浪潮中,迁移始终是企业与开发者绕不开的核心课题——从旧数据库升级到 PostgreSQL 社区版,从其他数据库(Oracle)迁移至 IvorySQL/PostgreSQL,每一步都藏着技术决策的智慧与实战踩坑的经验。 为汇聚更多迁移场景下的实战方案,助力开发者少走弯路,…...

MCP的天气预报的使用

`{{ formatTime(message.timestamp) }}<!-- 输入区域 --><div class="input-area"><el-input v-model="inputMessage" placeholder="请输入您的问题..."@keydown.enter.exact.prevent="sendMessage" /><el-butto…...

6款超好用的AI换脸软件,一键视频直播换脸(附下载链接)

随着AIGC的火爆,AI换脸技术也被广泛应用于娱乐、广告、电影制作等领域,本期文章系统介绍了市面上超火的6款AI软件 换脸整合包收录了全部6款AI工具,请按照需要选择下载: 百度网盘:https://pan.baidu.com/s/1LWMp7mvGc_76PDueFBv3tQ?pwd=fwu41.Roop 作为AI换脸领域的鼻祖,…...

lc1029-两地调度

难度:中等(后期巅峰)题目描述给定一个数组,长度为 2n,表示 2n 个人 每个元素都是一个二元组,前一个数表示去 a 的路费,后一个数表示去 b 的路费 需要让 n 个人去 a,另 n 个人去 b,求最小总花费示例 输入:costs = [[10,20],[30,200],[400,50],[30,20]] 输出:110 解释…...

pyAutoGUI 模块主要效果介绍-(2)键盘功能

pyAutoGUI 模块主要效果介绍-(2)键盘功能pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !import…...

(简记)时间复杂度分析 $\Omicron,\Theta,\Omega$ 的区别

严谨定义请前往OI-wiki渐进符号定义介绍 备考初赛。为了方便记忆,给出如下定义:对于 \(f(n)=\Theta(g(n))\),我们恰可以用 \(g(n)\) 乘上两个非 \(0\) 常数分别拟合出 \(f(n)\) 的上下界(可以取等号)。对于 \(f(n)=\Omicron(g(n))\),我们仅可以用 \(g(n)\) 乘上一非 \(0\…...

Java的运算符

java的二元运算符 package com.zhong.operator;public class Demo01 {public static void main(String[] args) {//二元运算符//Ctrl+D 复制当前行到下一行int a = 10;int b = 20;int c = 25;int d = 25;System.out.println(a+b);System.out.println(a-b);System.out.println(…...

2025年最强API安全解决方案:以智能风险监测重塑企业数据防护体系

2025年最强API安全解决方案:以智能风险监测重塑企业数据防护体系在数字化浪潮席卷全球的今天,应用程序编程接口(API)已成为企业数字化转型的核心枢纽。随着API调用量呈现指数级增长,其安全风险也日益凸显。数据泄露、未授权访问、业务逻辑滥用等安全事件频发,使得API安全…...

HTML打包EXE工具中的WebView2内核更新指南

在HTML一键打包工具推出了免费的WebView2内核后, 有很多朋友都开始使用它来发布自己的HTML项目。无论是一个内部管理系统的小工具,还是一个要分发给客户的桌面应用,只要原本是基于网页的,就能轻松地一键打包成一个 Windows 可执行程序。WebView2内核占用空间小, 而且免费, 深…...