C语言中结构体大小计算即存储分配

大话C语言:第42篇 结构体内存分配原则 每一个元素存入内存时,都会认为内存是以自己的宽度来划分空间的,因此元素存放的位置一定会在自己大小的整数倍上开始。vc6.0和Visual Studio环境下,8字节对齐,即存放double型变量的起始地址,必须是8的倍数,double变量占8字节。在64位系统下,以8字节为单位开辟内存。long int 在32位平台下,4字节对齐 ,即存放long int 型的变量,起始内存单元的编号是4的倍数即可。gcc环境下,4字节对齐,即存放double型变量的起始地址,必须是4的倍数,double变量占8字节。 阅读详情

C语言中结构体大小计算即存储分配

C语言中常用预定义的数据类型:

类型:         char short int long float double (long double)

大小(字节数):

  gcc3.2.2: 1      2    4   4     4     8      12

  Visual C++:1      2    4   4     4     8      8

ARM架构下被访问的变量大小形式可以为32位(字)、16位(半字)、8位(字节),当然,还有bit原子位操作。

typedef signed long  s32;
typedef signed short s16;
typedef signed char  s8;

typedef unsigned long  u32;
typedef unsigned short u16;
typedef unsigned char  u8;

定义一个结构体类型的时候(这里是定义结构体类型struct StrucTypeDef,不是定义一个结构体变量struct StrucTypeDef stru1或者结构体指针struct StrucTypeDef *stru2)并没有分配实际的地址空间(定义结构体变量在编译链接过程中给了实际地址,而结构体指针要显式的用malloc等形式申请栈内地址),通俗的说就是定义类型是没有实际分配空间的,而定义变量的时候会分配空间。

以下内容编辑前转自http://blog.youkuaiyun.com/lichunming83/archive/2009/10/31/4752818.aspx

Win32平台下的微软C编译器(cl.exe for 80×86)的对齐策略:

1) 结构体变量的首地址是其最长基本类型成员的整数倍;

备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能是该基本数据类型的整倍的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。

2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);

备注:为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员之后加上填充字节(trailing padding)。

备注:结构体总大小是包括填充字节,最后一个成员满足上面两条以外,还必须满足第三条,否则就必须在最后填充几个字节以达到本条要求。

 4) 结构体内类型相同的连续元素将在连续的空间内,和数组一样。

5) 如果结构体内存在长度大于处理器位数的元素,那么就以处理器的倍数为对齐单位;否则,如果结构体内的元素的长度都小于处理器的倍数的时候,便以结构体里面最长的数据元素为对齐单位。

 

以下内容编辑前转自http://www.dzsc.com/data/html/2009-6-4/76676.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

  {

  char c1;

  int i;

  char c2;

  }

  struct stu4

  {

  char c1;

  char c2;

  int i;

  }

  虽然结构体stu3和stu4中成员都一样,但sizeof(struct stu3)的值为12而sizeof(struct stu4)的值为8。

  如果结构体中的成员又是另外一种结构体类型时应该怎么计算呢?只需把其展开即可。但有一点需要注意,展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。看下面的例子:

  struct stu5

  {

  short i;

  struct

  {

  char c;

  int j;

  } ss;

  int k;

  }

  结构体stu5的成员ss.c的偏移量应该是4,而不是2。整个结构体大小应该是16。

  如何给结构体变量分配空间由编译器决定,以上情况针对的是Linux下的GCC。其他平台的C编译器可能会有不同的处理。


实例讲解结构体和共用体内存分配机制 1.了解结构体和共用体 结构体: C 结构体 共用体:C 共用体 为什么内存分配时需要对其: 对其原因 2.结构体存储规则 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 结构体每个成员相对于结构体首地址的偏移量都是基本类型成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;(如下图目标空间成员与首地址的偏移量为4+首地址大小) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节 3.共用体存储规则 1)共用体的总大小为共用体最宽基本类 阅读详情

相关推荐

使用SSE流式输出(Javaweb前后端实战)

SSE(Server-Sent Events)是一种在Web应用中实现单向实时通信的技术。通过SSE,服务器可以主动向客户端发送更新,而无需客户端不断发起请求。这对于需要实时更新的应用场景(如聊天应用、实时数据监控等)非常有用。(服务端单向传输客户端,长连接)

记得开心一点嘛的博客 1万+

[转]关于结构体内存

C语言中常用预定义的数据类型: 类型: char short int long float double (long double) 大小(字节数):   gcc3.2.2: 1 2 4 4 4 8 12   Visual C++:1 2 4 4 4 8 8 ARM架构下被访问的变...

我的ACM空间 294

嵌入式设备的switch 以及PHY 芯片调试和选型 (1)

越来越的设备需要多网口的需求,于是需求搭配一个交换机实现网口的扩展。但是很多软件或是硬件工程师在实际选型和应用中经常会遇到一些问题。这里总结一下,避免大家采坑。 几个概念: MAC(介质访问控制),可以理解成数据链路层即可 PHY(物理性),简单理解层转成物理层的连接组件即可 控制接口(MDC/DMIO,I2C,...

睿峰的博客 1万+

嵌入式C-1

1)2进制、8进制、16进制的相互转换 1.进制的概念(只是一种计数的方法) 2.进制的转换 (1)2进制转换成16进制 2进制:0B 16进制:0X 通过8421码计算 例子: 方法1.通过8421码,先算2进制转换成10进制,再转换成16进制 注:不够四位的添0 方法2:电脑自带的计算器,程序员模式 HEX:16进制 DEC:10进制 OCT:8进制 BIN:2进制 (2)10进制转换成其他进制 原则:转成几进制就除几,余...

qq_52382474的博客 787

FPGA之道(22)VHDL基本程序框架

在介绍详细的VHDL语法之前,让我们先来了解一下VHDL代码的基本程序框架,这样可以让我们先对VHDL程序设计有一个整体的概念把握,进而在后续的VHDL语法学习中做到有的放矢。

Reborn Lee 8309

Robot Arm 机械臂源码解析

由于我们用的是步进电机,运动的时候是一步一步的,并不是平滑的,这里假设在一个平面上面,一个x步进电机,一个y步进电机。那么放大它们所走的轨迹就会是阶梯状的。而它们也只能沿着网格运动。相当于有了一个最小的分辨率,这个分辨率就是一步。如下图所示,如果x,y电机同时走就能走出45度的斜线。在三维空间里面运动也是如此,你应该可以想象的出来;首先,是updateActualPosition,用来时时更新此时的差补位置,得到的是一个路径与时间t的函数(其中路径的范围为0,1,时间范围为0,dist/v)...

爱吃炸鸡的小猪's blog 1万+

一文读懂C/C++ 结构体内存分配原则

C语言struct结构体极大的扩充了数据类型,其实就相当于C++中的类,C++为了保存对C的兼容也保留了结构体这个数据类型,不过一般C++中结构体都只有数据没有方法。 但是C/C++中结构体在内存中的大小是如何确定的呢? 其实 结构体在内存中的大小由以下两个规则确定; 1、当前总大小是下一个数据类型的整数倍(如果不满足则补齐,但是单字节最大补齐4/8位具体由当前所有单字节数据类型中最大的数据...

baihebeijixing的专栏 1702

22AP10 SS524 平替 海思HI3521DV200 可提供开发资料

入,突破了数字接口的视频输入性能瓶颈,提供两倍于前代产品的视频输入能力。视频编解码引擎、视频图像处理的算法效果及性能得到了进一步提升。芯片为客户产品提供了高性能、优异图像质量。推理引擎,支持多种智能算法应用。合丰富的外围设备及高速接口,该。解决方案,广泛用于模拟高清。产品应用开发的新一代专。四核处理器和性能强大的。

szhorsway的博客 1011

C语言中struct结构体中的内存如何分配

然后是double c 内存是8, 所以刚好。最后看整体内存为16是最大double(8)的倍数,所以不需要扩内存。2.struct整体的内存是里面最大内存成员的整数倍。而我写的,首先是char a 占一个内存,int b ,1不是4的倍数,所以到偏移量为4的地方存储。首先,它的原则是1.所在位置的偏移量(即我写的红色数字)是sizeof(类型)的整数倍。我们先来看一段代码;

Qianxueban的博客 635

Python爬虫:爬取健身平台运动数据(跑步、骑行轨迹)

通过分析这些运动数据,用户能够了解自己的运动趋势、运动成绩,并作出相应的调整。通过使用Strava的API,我们成功地获取了用户的运动活动信息和运动轨迹数据,并进行了存储与可视化。Strava的API提供了丰富的数据接口,能够通过OAuth2认证获取用户的运动数据,包括历史数据、运动轨迹等信息。Strava的API还提供了获取活动轨迹数据的接口,返回的数据格式通常是GeoJSON格式,适用于地图可视化。随着大数据技术的发展,运动数据的分析和可视化为个人健康管理、运动训练计划的优化等提供了强大的支持。

2201_76125261的博客 1075

使用conda环境python3.13和python3.12下安装vllm过程记录

使用conda环境python3.13和python3.12下安装vllm过程记录

没刮胡子的程序员专栏 885

C语言中结构体内存分配(内含数组与结构体版)----超级详细版

在网上看资料了很久,看的我头晕都没看懂,不如自己操作一遍,总结出来了经验。 首先我们要理解这几个概念: 1) 结构体变量的首地址是其最长基本类型成员的整数倍; 2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding); 3) 结构体的总大小为结构体最宽基本类型成员大小的 整数 倍,如有需要,编译器会...

山月藏匿浪漫、 1万+

基于STM32F103设计的智能门锁(支持多种开锁解锁方式)

这个智能锁模型是基于STM32平台开发的,支持多种开锁方式。其中,一种是使用RC522射频卡读卡器读取IC卡卡号和内部数据,并验证身份后开锁;另一种是通过连接蓝牙地址来确认业主身份,实现了蓝牙自动开锁功能;最后一种是通过ESP8266连接腾讯云物联网平台,并且用户可以通过微信小程序“腾讯连连”进行远程开锁和关锁。这样,用户就可以选择最方便的方式来进行开锁操作了。

3万+

C语言中结构体大小计算即存储分配(转载)

C语言中常用预定义的数据类型: 类型:         char short int long float double (long double) 大小(字节数):   gcc3.2.2: 1      2    4   4     4     8      12   Visual C++:1      2    4   4     4     8      8 ARM架构下被访问的变

PengPengQian的博客 800

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

结构体的内存存储细节

// // main.c // C语言学习 #include int main(int argc, const char * argv[]) { /* 数组内存寻址是从大到小 存储数组元素从小到大 数组的地址就是数组首元素的地址 */ int nums[3] = {1,3,5}; //定义结构

763

数学建模模型总结

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

C语言-自定义类型(结构体、枚举、联合)如此简单

本文详细介绍了自定义类型中结构体、位段、枚举、联合体等内容,包括它们如何声明、定义以及在内存中如何布局,通过此篇的学习会对有关自定义类型相关知识深入了解。

熬夜秃顶中...... 1019

C语言 结构体存储空间分配

这两天在看结构体,一直在琢磨结构体的存储空间分配的问题,琢磨了半天总算明白了。和大家分享一下,希望能有所帮助。相信大家都知道结构体里元素存储要对齐吧,话虽是没错,只是这个“对齐”里面包含了很多微妙的东西。首先详细的给出结构体内存存储空间分配的原则吧:编译器按照成员列表顺序一个接一个地给每个成员分配内存。只有当存储成员时需要满足正确的边界对齐要求时,成员之间才可能出现用于填充的额外内存空间...

Andy_Xu2014的博客 1680

C语言结构体对齐问题详解

C语言结构体对齐问题详解 测试环境32位机 WinXP: 编译器VC6(MS cl.exe ) 和 mingw32-gcc-4.5.2   1 结构体数据对齐(没有#pragma pack()宏定义) 结构体对齐可以总结为三个基本原则 ①数据成员对齐规则: 结构体的数据成员中,第一个成员从offset为0的地址开始,以后每一个成员存储的起始位置为该成员大小

YUAN1125的专栏 1139

C中结构体的存储分配

转载链接 对于C语言中结构体所占的存储空间的大小,也一直是笔试面试的常客,今天好好看了一下这方面,以前一直以为很清楚了,今天通过各种实际测试举例,发现原来还是没有搞透彻,好在现在是彻底懂了,所以和大家分享,希望能有所帮助。 提到结构体,相信大家都知道元素存储要对齐,话是没有错,只是这个“对齐”里面包含了很多微妙的东西。首先详细的给出结构体内存分配的原则吧:编译器按照成员列表顺序一个

CHANGQINGTENGCJM的专栏 500

C - 结构体内存分配

最近又捡起了C语言,遇到了大量对结构体操作的业务,在操作期间,发现对结构体在内存中的分配仍然存有一定的疑问。,经过学习,特把有关结构体内存分配的相关知识记录下来。 内存对齐:要了解结构体的内存分配,首先需要了解内存对齐的概念。之所以会有内存对齐的概念,是因为,在操作系统中,数据的存放时按照字节存放的,而结构体又不像数组,结构体中可以存放不同类型的数据,它的大小也不是简单的各个数据成员大小之和,限...

bailang_zhizun的博客 1万+

揭秘结构体内存对齐与位段存储

【摘要】本文介绍了结构体内存对齐和位段存储的规则与应用。结构体存储遵循特定对齐规则,成员变量需按对齐数整数倍地址存放,导致实际占用空间可能大于成员尺寸之和。位段通过bit位精确控制成员存储空间,但存在内存分配不确定性和跨平台限制。文章通过代码示例演示了结构体S1、S2、S3、S4的内存计算过程,以及位段A的存储方式,并指出位段操作的特殊注意事项,如不能直接使用地址运算符。最后解析了练习代码的内存布局,说明空白部分为内存浪费区域。

2401_86525813的博客 1347

【C】自定义类型总结(结构体、联合体、枚举)

🍁这篇博客介绍自定义类型,包含结构体、联合体、枚举;结构体部分的知识点尤为重要!

trong_ 的烂笔头 654

C语言笔记----2012年计算机联考真题

C语言笔记【2】 【2012年计算机联考真题】 某计算机存储器按字节编址,采用小端方式存放数据,假定编译器规定int和short型长度分别为32位和16位,并且数据按边界对齐存储,其C语言程序段如下: struct{ int a; char b; short c; }record; record.a=273; 若record变量的首地址为0xC008,则地址0xC008中的内容及record.c的地址分别为( ) A . 0x00 0xC00D B . 0x00 0xC00E C . 0x11 0x

娄零的博客 1万+
上一篇: latch和lock的区别
下一篇: 百度面经
Zhangjay
博客等级 码龄19年 20粉丝 41原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值