结构体内存对齐详解(同比C++类的大小计算)

C++:计算结构体和对象的大小 C++:计算结构体和对象的大小如何计算结构体的大小结构体的内存对齐为什么存在内存对齐如何计算一个对象的大小 如何计算结构体的大小 其实计算一个结构的大小的方法并不难,简单来说就是把结构体内的所有成员的大小相加就可以。但是,需要内存对齐那么究竟什么是内存对齐,又为什么要进行类型对齐呢? 结构体的内存对齐 结构体内存对齐主要有两个步骤: 1.结构体各成员对齐. 2.结构体总体对齐 结构体内存对齐规则: 1.结构体的第一个成员在存放在结构体偏移量为0的位置 2.其他成员变量要对齐到某个数字(对齐数)的整数倍 阅读详情

今天讲下结构体内存对其的问题:

因为结构体内存对齐问题算是面试或笔试时的常考问题,所以我选择单独开一篇来讲解一下!!!

这个问题我当时是有点懵逼的在看到的时候,不知道是怎么计算出来的。
终于经过一段时间我仔细看了计算规则和理解我算是弄明白了计算过程,下面我就来讲一下,有什么不对的也欢迎大家在下面评论指出!

1.结构体内存对齐是什么

结构体可以存储多种数据类型,这也就意味着结构体的大小不是简单的几个数据大小之和这样来计算,而是有一定的规则来对齐存储。因为限于内存的读取要求,这样效率会更高。
C / C ++中的每种数据类型都有对齐要求(事实上它是由处理器架构强制实现的,而不是由语言强制实施)。处理器将具有与数据总线大小相同的处理字长。在32位机器上 ,处理字大小为4个字节。

2.为什么要进行内存对其

原因1:
因为在32位操作系统(虽然64位操作系统,但是为了保证兼容性,编程仍然主要考量32位)中,数据总线是32位,地址总线是32位。
地址总线是32位,意味着寻址空间是按4递增的;数据总线32位意味着一次可读写4byte。

原因2:平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址 处取某些特定类型的数据,否则抛出硬件异常

下面来看个图为什么要内存对齐:

struct stu1  
{   
   char a;   
   int b;  
   char c;  
}  

请看stu1这个结构体如果不内存对其的话,结果会是如下图这样:

对其前:
在这里插入图片描述
对其后:
在这里插入图片描述
没有内存对其的话也就意味着要执行stu1时需要读取两次内存,这样就浪费了时间,数据一多效率更是大大降低,如果对其的话,一次就可以了,众所周知,I/O操作是很耗时的,编译器做出对齐的选择也就好理解了。

结构体内存对齐规则

1 第一个成员在与结构体偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。注意:对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。 VS中默认的对齐数为8,gcc中的对齐数为4 .
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是 所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

在32位机器上,各个数据类型的自然对齐字节数:

类型32位机器
char1
short2
int4
float4
double8
long4
longlong4

下面有几个例子我们来看一下:

typedef struct St{   //sizeof(St)=4字节
	char a;
	char b;
	short c;
}	St;

typedef struct St1{  //sizeof(St1)=6字节
	char a;
	short c;
	char b;
}	St1;

typedef struct St2{ //sizeof(St2)=8字节
	char a;
	char b;
	int c;
}	St2

typedef struct St3{  //sizeof(St3)=12字节
	char a;
	int c;
	char b;
}	St3;

我以上面的St1和St3为例讲解一下计算方法:
St1:
首先char a在偏移量为0地址处,大小为1字节,此时偏移地址变到了1,short c大小2字节和vs默认对其数取最小值则是2,所以short c要放在偏移量为2的整数倍的地址处,那只能为2,所以前面的char a默认填充一字节,short c存储后,占2字节,此时偏移地址变到了4,char b大小1字节和vs默认对其数8取最小值为1,所以要存储在偏移地址为1的整数倍处,4就刚好可以,所以存放char b后偏移地址变为5,但此时结构体的整体大小要为该结构体中最大对其数的整数倍,该结构体中最大对其数为2,所以该结构体整体大小为6个字节。

St3:
首先char a存放在偏移地址为0的地方,大小1字节,偏移地址变为1,接下来存放int c,大小4字节和vs默认对齐数8取最小值为4,所以int c要存放在偏移地址为4的整数倍处,4就可以,所以char a默认填充3字节,偏移地址变为4,存放int c后,偏移地址变为8,char b为1字节和vs默认对齐数8取最小值为1,所以此时的8就刚好满足1的整数倍地址处,存放char b后偏移地址变为9,但结构体整体大小要为结构体中最大对其数4的整数倍,所以该结构体大小为12个字节。

最后再看一个结构体嵌套的情况:

typedef struct St4{
	char d;
	struct St5{
		char a;
		int b;
		char c;
	};
	double e;
	char f;
}	St3;

St4里还嵌套了一个St5,这就需要利用我上面说的来做了:
嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数的整数倍(含嵌套结构体的对齐数)的整数倍。

讲解:St5的对齐数是4,St5是12个字节,而St4结构体的最大对齐数是8(含St5来看了的),所以现在开始计算,首先char d在偏移地址0处1字节大小,然后偏移地址变为1,char a可以直接存储大小1字节,此时偏移地址变为2,int b大小4字节,必须放在偏移地址为4的整数倍的地方(因为4和vs默认对齐数8取最小值),偏移地址就变为4,存放int b后偏移地址变为8,8满足char c 1字节(因为1和vs默认对齐数取最小值为1),存放char c后偏移地址变为9,因为St5最大对其数为4,所以走完St5后偏移地址要变为4的整数倍,则为12,下来存储double e,8个字节,偏移地址要为8的整数倍(8和vs默认对齐数8取最小值),则偏移地址变为16,存储double e后偏移地址变为24,24满足char f 1个字节,所以存放char f后偏移地址变为25,结构体St4整体大小要为St4中最大对齐数(8)的整数倍,则为32字节大小。

如果上面的结果你都能算出来的话,说明你已经基本懂得了结构体内存对齐的计算方法。

以上过程我都写的很细致了,如果有什么不懂的请在下方评论留言,我会及时解答!

C/C++内存对齐 什么是内存对齐 还是用一个例子带出这个问题,看下面的小程序,理论上,32位系统下,int占4byte,char占一个byte,那么将它们放到一个结构体中应该占4+1=5byte;但是实际上,通过运行程序得到的结果是8 byte,这就是内存对齐所导致的。 //32位系统#include<stdio.h>struct{ int x; char y;}s;int main(){ printf... 阅读详情

相关推荐

用Python+OpenCV搞定线激光相机标定:从棋盘格到3D点云的保姆级实战

本文详细介绍了使用Python和OpenCV进行线激光相机标定的全流程实战,从硬件准备到3D点云重建。涵盖相机内参标定、激光平面方程拟合、三维重建等关键技术,提供完整的代码实现和工程优化建议,帮助开发者实现毫米级精度的工业检测和三维测量系统。

weixin_29227425的博客 284

C语言字节对齐(以32位系统为例)

1. 什么是对齐?    现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序地一个接一个地排放,这就是对齐。 2.计算机为什么要对齐?    各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某

yinsexingkong的博客 665

大模型驱动时序量化因子自动优化:从WorldQuant回测到实战策略

本文探讨了如何利用大模型驱动时序量化因子的自动优化,构建从创意生成到实战验证的完整流程。通过结合WorldQuant回测平台,搭建自动化流水线,详细拆解了因子生成、回测验证与迭代优化的核心模块。文章分享了从初版实现到进阶优化的实践经验,并指出提示词工程与领域知识注入是关键,旨在实现人机智能协作,提升量化策略研发效率。

wdx012345的博客 803

C/C++内存对齐以及类的大小计算详解

内存对其规则:(1)结构体第一个成员的偏移量(offset)为0,以后每个成员相对于结构体首地址的 offset 都是该成员大小与有效对齐值中较小那个的整数倍,如有需要编译器会在成员之间加上填充字节。(2)结构体的总大小为有效对齐值 的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。 类作为一种类型定义是没有大小可言的,这里的大小指的是类的对象所占的大小,使用sizeof对一个类型名操作,得到的是具有该类型实体的大小,计算遵循结构体的对齐原则。类的大小与普通数据成员有关,与成员函数和静态成员无

一抹阳光的博客 1807

robomimic实验复现全流程:从数据集下载到训练视频生成

本文详细介绍了机器人模仿学习项目RoboMimic的完整实验复现流程。内容涵盖从使用Conda创建Python 3.8隔离环境、安装RoboSuite仿真器和MuJoCo物理引擎,到下载并探索数据集、配置与启动模型训练,最后进行模型评估和生成策略执行视频。该指南旨在帮助研究者和开发者高效搭建实战环境,规避常见问题,快速验证算法或应用于实际场景。

weixin_29089057的博客 518

Zabbix 简介、优缺点、基础原理

(8条消息) Zabbix 的基础概念、原理和架构_Lee木木的博客-优快云博客_zabbix架构类型Zabbix 的基础概念、原理和架构_Lee木木的博客-优快云博客_zabbix架构类型 --------------------------------------------------------------------------------------------------------------------------- 一、Zabbix 简介 Zabbix是由A...

weixin_50196615的博客 2037

c++中的内存字节对齐

最近游戏项目开发中遇到一个小问题,客户端unity开发用的C#,但需要调用C++中的函数进行消息加密,调用DLL中的接口时,C#中的结构体需要传入到C++中进行操作,但是由于C#中的消息头定义的比较苟且,没有提供一个跟C++中一一对应的结构体,导致加密后再解密出错,最后发现时内存字节对齐的问题,在C++消息头定义处加入 #pragma pack(push, 1) #pragma pack(

peter_teng的专栏 710

从零打造高速 SerDes 系统:一步步教你生成 IBIS-AMI 模型!(含Simulink实操)

一个完整的 SerDes 系统,不止是电路设计,更是 SI 仿真、IBIS建模、系统验证三位一体的过程。用 MATLAB 的 SerDes Designer + Simulink 组合拳,不仅可以快速完成设计,还能无缝衔接工业标准流程,非常适合个人学习 & 企业验证。如果你还没用过,建议马上动手试一遍,毕竟:“光说不练假把式,跑出眼图才是王道!”🔥。

weixin_43199439的博客 1143

C/C++ 结构体字节对齐详解

发现在当前很多对结构体字节对齐的分析都有错误,这里从实际测试到理论分析,使用的平台是linux 32位。 一.什么是字节对齐,为什么要对齐?        现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的

shixiaoguo90的专栏 921

[AI] 嵌入模型选择:bge / text-embedding-3 / Jina Embeddings 对比与选型指南

摘要: 本文对比了BGE-M3、OpenAI和Jina三种主流嵌入模型在语言覆盖、性能、延迟、维度和成本等维度的差异。BGE-M3适合中文场景,本地部署成本低;OpenAI API多语能力强但依赖网络;Jina在多语表现突出但需关注商用许可。测试显示BGE-M3本地延迟3-6ms,OpenAI API延迟200-600ms。选型建议:隐私场景选BGE本地部署,多语低维护选OpenAI,高精度选Jina。部署时需注意批处理优化、向量库压缩和商用许可等问题,建议建立评测指标并监控关键指标。

每日出拳老爷子的博客 428

RK3568平台开发系列讲解(中断及异常篇)中断下半部:中断线程化

以前用 work 来线程化地处理中断,一个 worker 线程只能由一个 CPU 执行, 多个中断的 work 都由同一个 worker 线程来处理,在单 CPU 系统中也只能忍着 了。少数中断不能线程化,典型的例子是时钟中断,有些流氓进程不主动让出处理器,内核只能依靠周期性的时钟中断夺回处理器的控制权,时钟中断是调度器的脉搏。中断处理线程是优先级为50、调度策略是SCHED_FIFO的实时内核线程,名称是“irq/”后面跟着Linux中断号,线程处理函数是。,说明是线程化的中断,那么唤醒中断处理线程。

内核笔记 435

【C/C++】一篇通俗内存对齐(结构体/类 大小计算)

通过本章你能具体的了解到,如何计算出一个类的大小,并且了解其中到底是如何算的以及了解到为什么需要内存对齐这种算!

溟洵的博客 2210

把 SAP 输出稳稳落到 PDF:从 SPAD 前端打印到 ABAP 程序级转换的一套方法

摘要:本文介绍了三种在SAP系统中将报表输出转为PDF文件的方法。路线A通过SPAD配置前端输出设备,结合Windows打印机设置实现用户交互式PDF保存;路线B在SP01事务码中将已有Spool请求另存为PDF,适用于补救导出;路线C通过ABAP程序自动转换Spool为PDF,适合批量处理。文章详细说明了配置步骤,并针对常见问题(如乱码、文件格式错误等)提供了排查思路。三种方案分别适用于不同场景,用户可根据实际需求选择最合适的PDF导出方式。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 221

C C++内存对齐以及特殊类的大小

C C++内存对齐以及特殊类的大小

wtl666_6的博客 6480

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C++ 中结构体大小的计算方式

前言: 说起来C++还真是一门神奇的语言,就像你的GirlFriend一样晦涩难懂,你永远不知道下一秒她的心情会是什么样的,不过好在C++它终究还是一门编程语言,工具毕竟是死的,既然是死的那就好办了,总有方法来对付它。当你点进这篇文章或许是正带着疑惑而来的,或者曾碰到过结构体的大小飘忽不定不知道怎么计算,又或许你还没有遇到过这样的问题,不过也没关系所谓未雨绸缪也不是一件坏事,今天就来给大家讲一下C...

尼克不可的博客 5726

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

C++ 类、结构体、内存对齐

结构体与类的核心区别在于:结构体是值类型,内存栈分配,不支持继承;而类是引用类型,堆分配,支持继承。C++中结构体成员默认public,类默认private。结构体大小计算需要考虑内存对齐,确保成员偏移量是自身大小的整数倍

平平无奇的小甜菜 1246

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

c++结构体内存对齐

本文讨论c/c++内存对齐方式与原则,图文并茂说明,还有空结构体对齐特例。

noevil的博客 1759

C++ 内存布局与字节序详解:类大小、结构体对齐、大小端与字节序转换

内存对齐(Memory Alignment)是指将数据按照其数据类型的要求存储在内存中的方式。由于不同的数据类型对内存存储有不同的要求,内存对齐旨在提高访问效率,确保数据按正确的边界存储,从而避免性能损失或者硬件异常。对于第二问,上面的内容以及进行了解释。大小端是指在多字节数据类型(如intfloatdouble等)在内存中的存储顺序。它决定了数据的各个字节在内存中是如何排列的。大端(Big-endian):高位字节存储在低地址,低位字节存储在高地址。小端(Little-endian)

卜及中的博客 1745

内存对齐和类、结构体大小计算

通过以上分析可以得出,在结构体中,不同的数据成员排序方式可能导致结构体的大小不一样。这就要求我们根据实际情况分析结构体的数据成员,以达到最优的定义方式。结构体对象使用少的时候可能只差几个字节的内存,这无关紧要。但是如果我们定义的是一个链表,链表元素是结构体方式定义的,当链表长度增大时,那这节省的内存空间就不可忽视了。结构体内存对齐字节数可以通过#pragma pack(n) 的方式来指定。如果某些时候我想4字节对齐,有些时候我又想8字节对齐,那么怎么解决这个问题呢?

weixin_40332490的博客 952

计算结构体大小:内存对齐详解

对于同样的结构体成员,他们相互之间的顺序位置不同就会导致整个结构体大小的不同,本文旨在探讨为什么会出现这样的情况,以及如何计算结构体的大小

luming的博客 376

【C++】结构体内存对齐规则

详细解决结构体内存对齐规则,这还不点进来看看~

小羊study_sheep的博客 2304

C++ 结构体内存对齐

血的教训?面试被问到结构体内存对齐,哑口无言!

cpp_learner的博客 2223

【C/C++】结构体的大小 VS 类的大小 ( 详解 “内存对齐规则“ )

内存对齐 文章目录内存对齐1、什么是内存对齐?为什么要内存对齐?2、内存对齐的规则是什么?3、如何修改默认对齐数?如何计算结构体的大小?4、什么是位段?什么是联合体?如何计算它们的大小?5、C++中既有类的属性(成员变量)也有类的方法(成员函数),那么类的大小又是如何计算的?对于一些特殊的类,比如:仅有成员函数的类、空类的大小又是如何计算的? 1、什么是内存对齐?为什么要内存对齐? 首先先看一下面两段代码: typedef struct S1 //环境:VS { char a1; in

Sunnyside_ 836

C/C++结构体的内存对齐详解(深入探究结构体在内存里的保存形式)

结构体内存对齐

qq_45315034的博客 1384

C/C++中的内存对齐详解

C/C++内存对齐:深度解析与应用

m0_71974552的博客 2540

C++结构体内存大小计算规则

向DeepSeek提问:在C++中,结构体变量所占内存大小的计算。

hanqing1972的博客 1402
上一篇: Linux之线程(1)
下一篇: C++类和对象(1)
Python_programer
博客等级 码龄9年 25粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值