C结构体对齐

C++ 结构体对齐详解 在C++中,结构体(struct)的对齐是指编译器为确保结构体成员在内存中的地址满足特定的对齐要求而进行的调整。对齐有助于提高访问速度,但同时也可能导致内存空间的浪费。默认对齐:通常情况下,最好使用编译器的默认对齐方式,以获得最佳性能。手动对齐:只有在明确知道需要节省内存,并且能接受性能损失的情况下才使用手动对齐。理解和控制结构体的对齐对于编写高效、可靠的C++程序非常重要。希望这篇详解能够帮助你更好地掌握结构体对齐的概念和应用。 阅读详情

因为我看C++对象模型的时候,遇到了几个内存布局都是有关于对齐的一些细节,故此对结构体对齐再做一份小结,有人说:结构体对齐这个东西是依赖于编译器的,因此不用去研究,真的嘛?

 

也许是,也许不是,要看你是做那个行业的了,如果你是做系统地层,网络通讯,嵌入式系统的,一个字节的节省,也许对你是很大的期望呢。虽然具体的对齐方式是因编译器而异,但是对齐的基本原理是不变的,那个原理也许能指导我们编写程序的时候按照某个原则去进行。

 

不过,既然你用到了C或者C++,就多数是和系统底层有缘之人了,你说是嘛?呵呵。

 

现在先说在windows x86 32位机子下的MS vs2005编译器(就是:cl.exe for x86)下的对齐规则:

 

比如以下的结构体定义:

 

struct A

{

    int i;

    double d;

    char c;

};

 

问sizeof(struct A)在vs2005的大小?

 

现在说一下cl.exe(就是微软vs2005的编译器进程)在默认情况下是怎么做的:

 

1、对齐量的确定:找到A中最大的基本类型成员的大小,在本例中是8(double的大小).

 

2、当定义一个结构体变量struct A aA; 的时候,aA的起始地址要被由1确定的对齐量整除,在这个例子里,aA的起始地址一定要能被8整除)

 

2、然后开始分配int i,4字节的空间;再分配double d;注意double 是8字节,所以要分配在被8整除的地方,因此int  i后面空了4字节填充;

 

3、然后,分配char c;1字节,这个时候struct A的大小是4(这是int i;的) + 4 (这是填充的) + 8(这是double d;的) + 1 (这是char c;的)= 17;

 

4、最后,要求结构体总的大小要能被由1确定的对齐量整除,在这里是说struct A的大小要能被8整除,所以还要加上7字节的填充字符,一共是24字节。

 

从这里可以看出,vs2005的编译器的结构体填充有这样的规则(默认情况下,这个默认情况可以通过工程属性上面的选项修改):

 

1、对齐量的确定:结构体中最大的数据成员的字节数

 

2、当定义一个结构体变量的时候,起始地址一定能被确定的对齐量整除;

 

2、分配每一个成员的时候,该成员相对于起始地址的偏移(offset)要能被该成员的大小整除;

 

3、结构体总的大小能被确定的对齐量整除;

 

 

 

扩充的字节叫做pad(填充字节)

 

 

下面看linux g++ 3.4.3编译器在x86 的32位机子下的默认规则,那相对简单一些:(相当于VS2005中将对齐情况改成4字节对齐)

 

对齐的方式默认是4字节,所以每个成员都按照4字节方式对齐即可。上面的结构体的大小就是:

 

4 (int i;的大小) + 8(double 的大小) + 1(char 的大小) + 3 (为了4字节填充而补充的字节) = 16字节;

 

至于gcc的结构体变量的首地址分配的特征一时也找不到,还望各位多多指教。谢谢。

 

最后,如果定义一个没有任何成员的结构体,struct A{}; 该大小是多少呢?是1字节。如果定义了两个结构体变量struct A a1, a2; 1字节的填充能够使a1和a2的地址区分开来!

 

还有其他的编译器和操作系统就不是我所能知的了。

 

那么,这些规则也许不尽相同,但是给了我们一个编程时候的注意点,就是:

 

定义结构体的时候,成员最好能从大到小来定义,那样能相对的省空间。(至少不会比别的顺序差,一般情况下哈。)

 

比如以上的结构体,如果能这样定义:

 

struct A

{

    double d;

    int i;

    char c;

};

 

那么,无论是windows下的vs2005,还是linux下的gcc,都是16字节。

 

对齐情况还可以通过各个编译器给出的特性在代码中改,不过我没用过,就没有发言权,各位又需要可以参考别的文章。

 

以上的过程和推论是我看别的文章和上机试验的结果,如有不对之处,请各位指教,谢谢。

 

 

再说一点,对于有嵌套的情况,vs2005下的对齐我也不大确定,不过我的分析如下:

 

struct A

{

    char c;

    double d;

    int i;

};

 

struct B

{

    struct  A a;

    char c;

};

 

这种情况下,分析B的大小;

 

1、对齐量的确定:包括A中的各成员比较的,递归下去,比较各个基本类型成员的大小,去最大值,为8(double的大小);

 

2、起始地址和上面的一样,要求B的变量的其实地址能被8整除;

 

3、关于B中struct A a;的偏移和大小和将a单独作为结构体变量的时候一样(那样方便赋值运算)

 

剩下的和上面的规则相同;

 

所以:B的大小就是24(struct A)+ 1(char) +7(pad) = 32字节;

 

不知正确与否?还请诸位评判。

C语言——结构体内存对齐规则 C语言结构体内存对齐规则: 1. 第一个成员在与结构体变量偏移量为0的地址处。 2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。 4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。 附1: 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的值为8 接下来楼主用一些例子来帮助大家理解结构体对齐规则(注:楼.. 阅读详情

相关推荐

【C语言】结构体内存对齐

本文探讨了C语言中结构体和枚举的内存对齐与使用规范。在结构体部分,详细分析了内存对齐规则:成员按对齐数(编译器默认对齐数与成员大小的较小值)的整数倍地址存放,结构体总大小为最大对齐数的整数倍。通过多个示例演示了不同排列方式对内存占用的影响(如S1占12字节而S2仅8字节),指出内存对齐以空间换时间的本质。结构体传参建议传递地址而非整个结构体以避免性能损耗。 位段部分介绍了通过冒号指定成员比特位数的语法特性,但其存在跨平台兼容性问题。枚举类型相比#define具有类型检查优势,默认从0开始递增赋值

小白要加油的博客 1824

C++结构体字节对齐

结构体为什么要进行字节对齐?主要原因是加快变量在内存中的存取速度.我查了相关讨论对齐规则的资料,决定自己再整理一下. 对齐主要有两方面,一个是结构体里面的变量字节对齐,一个是结构体本身在进行对齐. 本文中基本数据类型占据大小分别为sizeof(char)=1.sizeof(short)=2,sizeof(int)=4,sizeof(float) =4,sizeof(double)=8 一 基

iaibeyond的专栏 3775

C语言-结构体内存对齐

结构体内存如何对齐? 为什么存在内存对齐 ? offsetof - 宏

linkang007的博客 1254

【C/C++】结构体对齐详解

如果结构体成员没有按照对齐要求排列,可能会导致结构体变量的大小增加,从而增加传输或存储的开销。结构体内存对齐是由编译器自动完成的,编译器会按照一定的规则将结构体成员按照一定的字节对齐方式排列在内存中。结构体成员的对齐方式通常按照其大小来确定,例如char类型通常按照1字节对齐,int类型通常按照4字节对齐,double类型通常按照8字节对齐等。结构体内存对齐是指编译器在分配结构体变量内存时,为了提高访问效率和内存对齐要求,按照一定规则将结构体成员按照一定的字节对齐方式排列在内存中的过程。

Michael 2561

C语言中的结构体对齐是什么?如何控制结构体对齐方式?

结构体对齐是指如何在内存中安排结构体的成员,以便使它们在内存中对齐到合适的边界位置。在许多计算机体系结构中,访问未对齐的内存可能会导致性能下降或引发硬件异常。因此,结构体对齐是一种重要的优化机制,它确保结构体成员被合理地分配到内存中,以最大程度地提高程序的性能。结构体对齐的主要目标是确保结构体的成员在内存中的地址是某个固定值的倍数,通常是成员的大小或特定硬件要求的大小。这个固定值称为对齐边界或对齐因子。结构体对齐的方式可以因编译器和目标硬件而异。

weixin_68551689的博客 2293

视觉检测在激光打码字符检测上的检测案例

在机器视觉检测技术中,OCR识别是比较典型的应用,应用的场景也比较丰富,基本上在制造业,每个工厂或者印刷厂都会用到视觉OCR识别检测,OCR字符识别的原理很简单,通过图像分割后,对字符进行学习、命名。在工业相机拍摄图像后,软件进行处理,从而读取结果。 随着技术的发展,激光打标技术被更多的应用在生产过程中,由激光打标代替油墨进行字符印刷,速度更快、效果更好。 但是随之而来的是在视觉检测上带来的影响,目前市面上应用的字符检测设备大多是由集成商单独开发的软件,在检测油墨印刷时,图像上的字符没有断点,非常连贯,所需

视觉检测设备-视觉检测系统-单张检测设备-卷料印品检测 1462

c++ 结构体对齐

这是因为将默认对齐字数改为1之后,在使用规则1 2 3进行计算的时候,都让1和之前大小取最小值,因为之前默认为8,所以可以获得之前的结果。将当前对齐字节数压入栈顶,并设这这个值为新的对齐字节数,也就是当前对齐字节数并没有改变。n只能是1 2 4 8 16中的任意值,表示设置当前对齐字节数。会在编译阶段给出一个警告,说明当前对齐字节数,默认为8。将当前对齐字节数压入栈顶,并设置n为新的对齐字节数。会弹出栈顶对齐字节数,并设置为新的内存对齐字节数。弹出栈顶并直接丢弃,设置n为其新的内存对齐字节数。

qq_43534165的博客 775

Unity Hub报错The Hub as encountered a critical error and must close

如果注册表HKEY_LOCAL_MACHINE\SOFTWARE\Unity Technologies\这个目录下有Hub文件,直接删掉然后重装就可以。C:\Users\Administrator\AppData\Roaming\Unity 作者:SevenVee。HKEY_CURRENT_USER\Software\Unity 下所有项,尝试过,卸载重装,清除临时文件无果后,最终决定删除所有与Hub有关的文件。重装unity后可以打开了。结果:卸载重装后还是会出现此问题。结果:重装后还是无法解决。

qq_42345116的博客 3638

c/c++--字节对齐(byte alignment)

的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法。这个功能是跟操作系统没关系跟编译器有关.//用法如下struct bbbchar a;int b;//直接按照实际占用字节来对齐,其实就是相当于按照1个字节对齐了//这里计算sizeof(st3)=5。

qq_37233070的博客 3671

小红书UID泄露风险揭秘:如何防止你的手机号被社工库关联(附防护指南)

本文揭示了小红书UID泄露的严重风险,详细解析了UID与手机号关联后被社工库利用的完整链条。通过分析黑产的数据整合技术,提供从基础到进阶的防护策略,包括密码管理、账号隔离和应急响应措施,帮助用户有效防范个人信息泄露风险。

ol789012345的博客 1505

【老生谈算法】可视化通道流中瞬时涡量场的算法实现与MATLAB源码分析——瞬时涡量场

本文旨在探讨可视化通道流中瞬时涡量场的方法,并通过MATLAB编程实现这一过程。涡量场作为描述流体旋涡强度和方向的重要物理量,对于理解复杂流体运动具有重要意义。本文首先介绍了涡量场的基本概念,随后详细阐述了从测量数据收集到涡量场可视化的完整流程,并给出了相应的MATLAB源码。通过实际运行该源码,我们展示了涡量场的可视化结果,并讨论了其在流动结构识别和动力学行为理解中的应用。关键词: 涡量场;流体运动;MATLAB;可视化;PIV一、引言。

m0_53407570的博客 1124

C语言--结构体内存对齐规则

C语言结构体对齐步骤: 结构体各成员对齐. 结构体总体对齐 C语言结构体对齐规则: 结构体(struct)的数据成员,第一个数据成员存放的地址为结构体变量偏移量为0的地址处. 其他结构体成员自身对齐时,存放的地址为min{有效对齐值为自身对齐值, 指定对齐值} 的最小整数倍的地址处. 注:自身对齐值:结构体变量里每个成员的自身大小 注:指定对齐值:有宏 #pragma pack(N) 指定的值,这里面的 N一定是2的幂次方.如1,2,4,8,16等.如果没有通过宏那么在32位Linux主机上默

guanyunpeng's 3万+

基于STM32的宠物智能照护嵌入式系统设计

嵌入式系统是实现物联网终端设备本地化感知、决策与执行的核心技术载体,其关键在于多传感器融合、低功耗执行控制与轻量级云边协同。本文围绕环境监测(温湿度、烟雾、余粮)、机电执行(步进电机食盘、继电器风扇)和可靠通信(MQTT+ESP8266)三大技术主线,深入解析STM32F103在资源约束下的外设调度策略、ADC采样抗干扰设计、DHT11时序精准控制及HX711称重滤波算法等工程实践要点。系统强调本地闭环优先原则,确保离线基础功能可用,同时通过阿里云IoT平台实现远程监控与告警联动,为中小型智能硬件项目提供可

weixin_29155599的博客 293

【C语言】结构体字节对齐

在C语言中,结构体(struct)的字节对齐(也称为内存对齐或数据对齐)是一种内存布局的优化手段,它涉及到结构体成员在内存中的排列方式。字节对齐的主要目的是提高内存访问的效率,因为大多数现代处理器在访问按照其字长(如32位或64位)对齐的内存地址时速度更快。自然对齐(成员对齐):每个成员变量的起始地址都是其大小的整数倍。例如,如果一个结构体包含一个int(假设int是4字节)和一个char(1字节),那么int成员的起始地址应该是4的倍数,而char成员的起始地址可以是任意地址。结构体对齐。

v13111329954的博客 1430

人工智能学习之机器人路径规划优化

A* AStar 人工智能 机器人路径规划优化

RongLin02的博客 7073

车载以太网-ARP 动态 静态

车载以太网-ARP 动态 静态

天赐好车的博客 409

c语言结构体对齐

C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容虽然很基础,但一不小心就会弄错。写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?开始学的时候,也被此类问题困扰很久。其实相关的文章很多,感觉说清楚的不多。结构体到底怎样对齐?有人给对齐原则做过总结,具体在哪里看到现在已记不起来,这里引用一下前人的经验(在没有#pragma pack宏的情况下):原则1、普通数据成员对齐规则:第一个数据成员放在offset为0

renrenhappy的专栏 4215

iqoo11如何获取root权限?

🏆本文收录于专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家!持续更新中,up!up!up!!

**My Coding Family** 5819

简单易懂的C结构体对齐原则

简单易懂的C结构体对齐原则 结构体的对齐原则非常简单,只需要理解两个点就能透彻理解结构体对齐。分别是: 结构体内成员的对齐长度,该长度就是该成员的类型长度; 结构体的对齐长度,该长度默认情况下是成员类型长度最长的那成员的类型长度; 详解 原则1:(没有使用#pragma pack指令) 结构体每个成员都有自己的对齐原则,该成员的对齐原则为该成员的类型长度的整倍数。 A. 简单示例如下(暂时先不关注结构体的总长度): struct A { char a; short b; int c; }

星空漫步者 1464

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

蓝牙模块HM-10手册

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

C语言结构体对齐详解

详解如何快速判断C语言结构体占用空间大小

只为改变自己 5860

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C语言深度理解之——结构体内存对齐

C语言深层理解之结构体在内存中的存储方式

2301_80220607的博客 2115

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C语言结构体的字节对齐

本文详细介绍了C语言中结构体字节对齐的规则,并根据该规则拓展了一些CPU读取系统内存的一些知识,联系到实际开发中,鼓励读者对提高自己编程能力的思考

Royi的学习博客 1596

c语言中结构体以及结构体中的对齐

结构体定义和结构体变量的声明,结构体变量的使用,结构体中的对齐方式以及相关计算和示例,为什么要结构体对齐

cyz322649的博客 1358

C语言结构体对齐总结

现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问都可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就是对齐。 结构体对齐包括两个方面的含义 1)结构体总长度;  2)结构体内各数据成员的内存对齐,即该数据成员相对结构体的起始位置; 一、字节对齐的原因大致是如下两条 1、平台原因(移植原因):不是所有的硬件平台都能访问

E_ROAD_BY_U的博客 788

c语言结构体的对齐方式,C语言结构体内存的对齐知识详解

前言在前面的章节中,我们谈到了C语言中整数以及浮点数的储存今天,我们来谈一谈一些关于结构体内存的知识。我们先来看一个例子:struct S1{char c1;int i;char c2;};大家来猜猜这个结构体S1的内存是多少?相信会有人给出 6 的结果,他们或许是这样想的,两个 char 类型分别为一个字节,一个 int 类型又为4个字节,加起来刚好为6个但是结果真是如此吗?我们来看看运行结果:...

weixin_29443363的博客 2921
上一篇: linux内核学习网站
下一篇: FileInputStream 与BufferedInputStream
hohaixrh
博客等级 码龄20年 19粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值