数据对齐 & 结构体的大小

C/C++中结构体内存对齐(边界对齐),#pragma pack设置 一、首先,为什么要进行内存对齐,即在内存中为什么要这么存放数据呢??? 原因一:在内存中存放数据是为了给CPU使用,但是CPU从内存中读取数据并非是一个字节一个字节进行读取的,而是一块一块进行读取的,块的大小(具体和数据总线宽度等有关)称为内存读取粒度(memory granularity)。例如:CPU一次从内存读取8字节,而当一个int(4字节)存储在如下位置时,CPU如何获取该int值呢?... 阅读详情

数据对齐:

如果一个变量的内存地址正好是它长度的整数倍,它就称作是自然对齐的。

一些体系结构对对齐的要求非常严格。RISC系统,载入未对齐的数据会导致处理器陷入(一种可处理的错误,trap)。还有一些系统可以访问没有对齐的数据,只不过性能会下降。编译器会通过让所有的数据自然对齐来避免引发对齐问题。


看一下结构体大小的计算:

转载: http://blog.sina.com.cn/s/blog_5f77c7270100dnoy.html


运算符sizeof可以计算出给定类型的大小,对于32位系统来说,
sizeof(char) = 1; sizeof(int) = 4。
基本数据类型的大小很好计算,我们来看一下如何计算构造数据类型的大小。
    C语言中的构造数据类型有三种:数组、结构体和共用体。
数组是相同类型的元素的集合,只要会计算单个元素的大小,整个数组所占空间等于基础元素大小乘上元素的个数。
结构体中的成员可以是不同的数据类型,成员按照定义时的顺序依次存储在连续的内存空间。和数组不一样的是,结构体的大小不是所有成员大小简单的相加,需要考虑到系统在存储结构体变量时的地址对齐问题。看下面这样的一个结构体:
       struct stu1
       {
       int    i;
       char c;
       int j;
       };
先介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。显然,结构体变量中第一个成员的地址就是结构体变量的首地址。因此,第一个成员i的偏移量为0。第二个成员c的偏移量是第一个成员的偏移量加上第一个成员的大小(0+4),其值为4;第三个成员j的偏移量是第二个成员的偏移量加上第二个成员的大小(4+1),其值为5。
实际上,由于存储变量时地址对齐的要求,编译器在编译程序时会遵循两条原则:
一、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
二、结构体大小必须是所有成员大小的整数倍。
对照第一条,上面的例子中前两个成员的偏移量都满足要求,但第三个成员的偏移量为5,并不是自身(int)大小的整数倍。编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成8。
对照第二条,结构体大小等于最后一个成员的偏移量加上其大小,上面的例子中计算出来的大小为12,满足要求。
再看一个满足第一条,不满足第二条的情况
struct stu2
       {
       int   k;
       short t;
};
成员k的偏移量为0;成员t的偏移量为4,都不需要调整。但计算出来的大小为6,显然不是成员k大小的整数倍。因此,编译器会在成员t后面补上2个字节,使得结构体的大小变成8从而满足第二个要求。
由此可见,大家在定义结构体类型时需要考虑到字节对齐的情况,不同的顺序会影响到结构体的大小。对比下面两种定义顺序
struct stu3                              struct stu4
{                                      {
 char c1;                               char c1;
 int i;                                  char c2;
 char c2;                               int   i;
}                                      }
虽然结构体stu3和stu4中成员都一样,但sizeof(struct stu3)的值为12而sizeof(struct stu4)的值为8。
如果结构体中的成员又是另外一种结构体类型时应该怎么计算呢?只需把其展开即可。但有一点需要注意,展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。看下面的例子,
struct temp
       {
       short i;    +1
       struct
       {
          char c;  +5
          int j;   +6
       } ss;       +10+2
          int k;   +4
};             =16
结构体temp的成员ss.c的偏移量应该是4,而不是2。整个结构体大小应该是16。
注意在linux下时,整个结构体的大小应该是:
char对齐模数是1,short是2,int是4,float是4,double(linux是4,windows是8)
所以对于如下的结构体:(32位机,默认设置)
struct temp
 {
        int   i;       
        double  j;   
 };
对于在WINDOWNS系统下,整个结构的大小应该是16,在LINUX系统下,整个结构的大小应该是12
 
当控制结构的成员封装到内存并为模块中的所有结构指定相同的封装时。
#pragma pack(n)   是把所有的成员的对齐模数都设置为n,比如设置为1后,就是一个一个的挨着存放,结构大小也就是成员大小之和了。n必须小于默认的对齐模数,也就是说只能向小设,不能向大设

结构体占用内存大小如何确定?-->结构体字节对齐 | C语言 结构体字节对齐 阅读详情

相关推荐

详解结构体内存对齐

本文详解了结构体内存对齐,具体包括结构体内存对齐的规则、offsetof 宏的介绍和模拟实现、结构体内存对齐的原因以及如何修改默认对齐数。

melonyzzZ的博客 2321

如何计算结构体的大小

结构体的大小 运算符sizeof可以计算出给定类型的大小,对于32位系统来说, sizeof(char) = 1; sizeof(int) = 4。 基本数据类型的大小很好计算,我们来看一下如何计算构造数据类型的大小。     C语言中的构造数据类型有三种:数组、结构体和共用体。 数组是相同类型的元素的集合,只要会计算单个元素的大小,整个数组所占空间等于基础元素大小乘上元素的个数。

沉淀,累积 1159

C语言中的结构体大小计算与字节对齐

字节对齐是指将数据类型的变量存储在内存中时,按其类型所需的对齐要求来安排存储位置。对齐的目的是让处理器能够更高效地访问内存。char类型的变量占用 1 个字节,不需要对齐。int类型的变量占用 4 个字节,并且通常需要按 4 字节对齐,即它的起始地址必须是 4 的倍数。double类型通常需要按 8 字节对齐。字节对齐是一种内存优化技术,旨在确保数据按特定的字节边界对齐,以提高访问效率。结构体的大小不仅由各个成员的大小决定,还与字节对齐规则有关。

m0_62599305的博客 1457

计算结构体大小(32位系统)

计算结构体大小,32位系统下

A_lid的博客 1323

自旋玻璃(spin glass)、自旋冰(spin ice)和量子自旋液体(quantum spin liquid)(之二)

具有相同电荷的电子相互排斥。结果,为了在极其拥挤的环境中相互超越,他们不得不改变自己的行为。剑桥大学和英国伯明翰大学于 2009 年 7 月发表的研究表明,电子可以通过量子隧穿从金属表面跳到相近位置的量子线上,这样做后,将分离成两个准粒子,命名为的自旋子和全子。Van den Brink、Khomskii 和 Sawatzky 在 1997-1998 年对轨道子进行了理论上的预测。在 2011 年 9 月发给出版商的论文中报告了它作为一个单独的准粒子的实验观察结果。

qq_32515081的博客 1万+

开关电源辅助电源设计全流程拆解

地类型定义包含电路功率地(PGND)高压侧地,与主功率电路地相连整流桥负极、原边电感地、UC3842的功率地信号地(SGND)低压侧地,与控制/采样电路地相连副边整流管地、TL431地、MCU/运放地。

lyzh971103的博客 1473

结构体大小如何计算?

以下内容摘自此处: 作者:太平小小草 链接:https://www.jianshu.com/p/e772fff47465 来源:简书 结构体大小计算有三个原则: 一,结构体变量的首地址,必须是结构体 "最宽基本类型成员" 大小的整数倍(0被认为是任何数的整数倍)。 二,结构体每个成员相对于结构体首地址的偏移量,都是该成员的整数倍。 三,结构体的总大小,为结构体 “最宽基本类型成员” (将嵌套结...

椰树林YSL的博客 1万+

离线路径规划服务Graphhopper

离线路径规划服务Graphhopper 本文主要探索使用Graphhopper搭建离线路径规划服务,需要掌握一定的JAVA基础环境配置的知识 文章目录离线路径规划服务Graphhopper前言一、Graphhopper是什么?二、使用步骤1.下载Graphhopper2.从OpenStreetMap下载路图数据3.安装Graphhopper所需环境4.修改配置5.启动Graphhopper总结 前言 在外网环境中可以使用百度、高德等第三方的sdk用以实现路径规划的功能,由于项目的需要,在离线环境中需要使

Sysdark的博客 7560

【C语言】结构体的大小是如何计算的?(结构体对齐详解)

使用sizeof计算结构体大小,影响结构体内存大小的三种因素,结构体的对齐规则详解

C/C++领域,数据结构,linux,MySQl学习者 9963

智能体在车联网中的应用:第19天 智能体理论与初步实践 D30:阶段小结——在SUMO中使用TraCI控制预编程智能体

本文介绍了如何将强化学习从算法仿真迁移到交通系统实践,重点讲解了SUMO微观交通仿真平台与TraCI实时控制接口的架构。通过构建一个预编程驾驶智能体,演示了车辆从起点到目标点的导航控制。文章详细解析了TraCI的双向通信机制和事件驱动模型,对比了其与传统RL环境的差异,并提供了完整的Python实现框架,包括路网配置、车辆控制和基于向量场的导航逻辑。该实践为后续开发高级学习型交通智能体奠定了基础。

IT深耕十余载,大道之简 1479

QGis软件 —— 5、QGis增加线,并对线进行绘制、旋转、缩放、移动等基本操作

QGis软件 —— 5、QGis增加线,并对线进行绘制、旋转、缩放、移动等基本操作

8246

[收藏]内存对齐

看到chenzhp前辈总结的,很好,收着。 Win32平台下的微软 编译器(cl.exe for 80×86)的对齐策略: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。 2) 结构

jingziw的专栏 536

车载以太网测试-1【TC8物理层测试基础】

车载以太网物理层是车载网络的基础,负责将数字数据转换为适合在物理介质上传输的信号,并确保数据传输的可靠性、稳定性和高效性。它在车载网络系统中扮演着至关重要的角色,直接影响着车辆内部通信的性能和效率。1. 主要物理层标准车载以太网标准由IEEE 802.3和标准名称速率线缆类型编码方式应用场景100BASE-T1100 Mbps单对非屏蔽双绞线车载摄像头、传感器1 Gbps单对屏蔽/非屏蔽双绞线自动驾驶域控制器、高清视频10BASE-T1S10 Mbps单对双绞线幅移键控(ASK)

车载网络测试工程师的博客 4392

C语言结构体、共用体、枚举与位运算详解

共用体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。结构体是C语言中用于将不同类型的数据组合成一个整体的复合数据类型。枚举是一种用户定义的数据类型,用于定义一组命名的整数常量。

2302_81263197的博客 200

AI驱动的客户终身价值分析:深入理解公司的收入质量

客户终身价值(Customer Lifetime Value, CLV)是衡量客户在整个生命周期内能为企业带来多少利润的重要指标。传统的CLV计算方法往往过于简化,无法准确反映复杂的客户行为和收入模式。本文旨在介绍如何利用人工智能技术,特别是机器学习方法,构建更精确的CLV预测模型,从而帮助企业深入理解其收入质量。CLV的基本概念和商业意义传统CLV计算方法的局限性基于机器学习的CLV预测方法特征工程和模型选择策略实际应用案例和Python实现首先介绍CLV的基本概念和商业背景。

AI云原生与云计算技术学院 477

手把手实现3D肺结节检测:基于Faster R-CNN的从CT处理、训练到部署的五步代码级实战与避坑指南

亲爱的同学,当你能完整实现“3D Faster R-CNN肺部结节检测系统”,你会发现医学影像AI的毕设课题充满挑战与成就感。我们围绕3D Faster R-CNN模型,从数据处理、模型搭建到实验验证,一步步带你打造一个能精准检测肺部结节的智能系统,让你的毕设既体现技术深度,又能为肺部疾病早期诊断贡献实用价值。是专为3D医学影像设计的目标检测模型,能在三维CT数据中自动定位、识别肺部结节——这一课题兼具“临床价值”和“技术挑战性”,是毕设的优质选择,能充分展现你的工程能力和科研敏感度。

LXY_LOVE36的博客 308

结构体内存对齐(如何计算结构体的大小)

文章目录结构体内存对齐规则结构体大小计算 - 三步曲为什么存在内存对齐?设计结构体时的技巧修改默认对齐数 结构体内存对齐规则 我们知道,整型变量有自己的大小,浮点型变量有自己的大小,数组也有自己的大小,那么结构体有没有自己的大小呢? 回答是肯定的,结构体也有自己的大小,但是结构体的大小并不是简单地将每个结构体成员的大小相加就能得到。 结构体的大小计算遵循结构体的对齐规则: 第一个成员在与结构体变量偏移量为0的地址处。(即结构体的首地址处,即对齐到0处) 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址

2021dragon的博客 1万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

结构体大小的计算(结构体内存对齐)

学习过C语言的我们知道,整型变量有自己的大小,浮点型变量有自己的大小,数组也有自己的大小,那么结构体有没有自己的大小呢?回答是肯定的,结构体也有自己的大小。

平淡中造就不平凡 4415

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

【C/C++】结构体&内存对齐

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

花想云的博客 2371

廖雪峰Python教程[完整版]

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

C语言结构体的大小,结构体内存对齐

在自己正真了解过之前,一直认为结构体的大小就是结构体内部成员大小的总和。但当你去尝试打印结构体的大小时,会发现事实并非如此,也不会像你想的那样简单。给出这样的两个结构体,它们的元素完全相同,只是定义的顺序不一样。按照直觉来说,它们的大小都应该是两个字符和一个整形的大小的总和,也就是6。但是当我们实际打印出来之后会发现,struct S1的大小是8,而struct S2的大小是12。也就是说,结构体的大小肯定不只是由其成员的大小和数量决定,至少还会与其成员定义的顺序有关。

2302_80372340的博客 1308

c语言之内存对齐、结构体内存大小详解

结构体类型对我们来说并不陌生,然而,关于结构体内存的大小,也可以说是内存对齐吧,一直是个非常经典的问题,很容易出现,那么跟着博主来一起了解结构体的存储方式吧!

m0_65038072的博客 1414

结构体字节对齐详解

假如有个结构体A如下,请问它占用了几个字节?以我们的直观感觉,char占用1个字节,int占用4个字节,short占用2个字节,因此总共占用7个字节。真是这样吗?让我们运行实测一下,测试程序exampl.cpp编译并执行程序,结果如下所示每个结构体的占用空间如我们所知道的char是1,int是4,short是2,累加结果应该为7,但最后结构体占用的字节却是12个,这个就是结构体的。...

liaoyaonline的博客 4700

结构体内存对齐(结构体大小的计算)

文章目录结构体内存对齐规则 结构体内存对齐规则 我们知道,每种类型都有相应的大小,如int型占4字节,double型占8字节,char型占1字节;那么结构体也为一种类型,它的大小为多少呢? 我们可以举个栗子看一看 #include<stdio.h> struct S1 { char c1; int i; char c2; }; struct S2 { double d; char c; int i; }; int main() { printf("%d\n", sizeof(str

m0_56808122的博客 702

C语言结构体大小及对齐问题

写在前面: 本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。 目录 一、内存大小问题 二、分配问题 三、结构体分配的空间 四、内存大小对齐原则 五、其他 一、内存大小问题 有时候,我们在不同的编译环境,或者不同的机子上测试编译,会呈现不同的结果,于是我们会陷入疑问,内存的大小...

夏沫的杂物间 1864

C语言中计算结构体的大小

因此我们似乎很容易就能计算出这个结果:4+20+4+4=32字节但事实上结构体的大小并不是通过这样简单累加计算的。

sdkdlwk的博客 1万+

如何计算结构体变量的大小(结构体内存对齐)

在C语言中,变量由于类型不同在内存中开辟空间的大小不同,而结构体类型是一种特殊的变量类型,其可以是多个类型的集合,甚至结构体嵌结构体类型,那么结构体类型变量占内存空间的大小该如何计算呢?这也是一个特别热门的考点。

喜羊羊的博客 1076
上一篇: 为什么 tcp/udp 的端口号可以重复
下一篇: linux kernel setup_arch
windtakers
博客等级 码龄17年 94粉丝 197原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值