如何计算:结构体内存的大小(在结构体的考察中占据非常重要的地位)

简介: 如何计算:结构体内存的大小(在结构体的考察中占据非常重要的地位)

在之前的文章中,笔者就结构体的简单定义,初始化,等内容,进行了简单描述!!但是,对于int  ,double ,float ,char 等类型都有自己的大小,但是,对于一个结构体,它的大小该如何计算呢???确实是一个疑问??这个也是不少老铁,在刚学结构体时候的最大煎熬!下面,笔者来带领大家熟悉一下,结构体大小的计算!!


在讲解之前,需要大家知道一下几点:


1.结构体的第一个成员,直接对齐到相对于结构体变量起始位置为0的偏移处!!


2.从第二个成员开始,要对齐到某个对齐数的整数倍的偏移处!


对齐数:结构体成员自身大小和默认对齐数的较小值!


在VS中,默认的对齐数为:8


在Linus环境不设默认对齐数(对齐数是结构体成员的自身的大小)


3.结构体的总大小,必须是最大对齐数的倍数!!每个结构体成员都有一个对齐数,其中最大的对齐数就是最大对齐数!!


4.如果嵌套结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小:就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍!


下面笔者用代码加解析的方法来演示一下:


#include <stdio.h>
struct s1
{
  char c1;
  int i;
  char c2;
};
int main()
{
  printf("%d\n", sizeof(struct s1));
  return 0;
}

上面定义了一个结构体,里面存放有:char c1;    int i;   char c2; (我们先注意一下,结构体里面的先后顺序) char 占一个字节,Int 占4个字节!但是对于运行结果:12个字节????什么鬼这是??


0a2653c851af460fa595bd959398a8f1.png


不相信的各位老铁,可以在VS的x86环境下进行实现!读者可以自己进行验证!!


2d65d23f6d4748949b924e4057485923.png


对于结构体的仔细划分为:


6de278e6d6694ce5bb08e7e842b7e74b.png


经过上面的笔者必须知道的部分:1,2,3,三点,我们可以有:


12c3b7f3f8814309a195c64f051d4445.png


但是,笔者将上面的结构体的顺序,稍微改写一下:


struct s2
{
  char c1;
  char c2;
  int i;
};

请注意一下,先后顺序!!


对于这个代码,该结构体的大小,又是多少呢???想必,到此为止,各位老铁,不再是:1+1+4=6个字节了吧!!


请看这代码的运行结果:


34e8d716411043c08c7ffba9fbba23de.png


但是,这个结果是8,这个又是为什么呢??各位老铁,可以根据,前面的那个案列来分析一下:


92ba0822ed0b46e1ae72df8a17d3a45b.png


对于上面两个案列的简单讲解,想必大家也能理解了:如何来求结构体大小的方法!!


下面,笔者来带领大家,求一下:结构体成员,相对于起始位置的偏移量!!


offset是一个宏!!是用来计算:结构体成员相对于起始位置的偏移量的一个宏!


使用语法为:


offsetof(type ,member);

type 是指:哪个结构体类型! ,member 是指:成员名!!


下面笔者用代码加解析的方式来带领大家了解一下:


#include <stdio.h>
#include <stddef.h>
struct s1
{
  char c1;
  int i;
  char c2;
};
int main()
{
  printf("%d\n", offsetof(struct  s1 , c1));   //0
  printf("%d\n", offsetof(struct  s1, i));     //4
  printf("%d\n", offsetof(struct  s1, c2));    //8
  return 0;
}


上面代码的运行结果为:


d79b274929334152a6d38be91e2d1be3.png


这个在,笔者的讲解过程:


dfc80ca9d8004e6c9ddc00e8448ffc6a.png


因此,结构体的总大小,必须是:最大对齐数的倍数!


同理可得,我们也可以对


struct s2
{
  char c1;
  char c2;
  int i;
};

来进行同样的道理分析:


#include <stdio.h>
#include <stddef.h>
struct s2
{
  char c1;
  char c2;
  int i;
};
int main()
{
  printf("%d\n", offsetof(struct  s2, c1));   //0
  printf("%d\n", offsetof(struct  s2, c2));     //1
  printf("%d\n", offsetof(struct  s2, i));    //4
  return 0;
}


0a2653c851af460fa595bd959398a8f1.png


想必现在,大家对于该结构体的大小,目前没有什么问题了吧!!


对于嵌套部分的结构体,我们一样可以用这样的方法来进行求解!!相信大家都是可以求出来的!!


经过上面的结构体对齐的方法讲解:想必大家也有着:为什么存在内存对齐??有着疑惑!!下面笔者来进行简单讲解一下:


1.平台原因


不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处,取某些特定类型的数据,否则,抛出硬件正常!


2.性能原因


数据结构(尤其是栈)应该尽可能地在自然边界上对齐,原因在于:为了访问未对其的内存,处理器需要做两次内存访问,而对齐的内存访问,仅需要访问一次!


总的来说:


结构体的内存对齐是拿空间换取时间的做法!


那么设计结构体的时候,我们既要满足对齐,又要节省空间,就要做到:


 让占用空间小的成员尽量集中在一起!!


相关文章
|
4月前
|
存储 安全 数据库
阿里云服务器计算型、通用型、内存型主要实例规格性能特点和适用场景汇总
阿里云服务器ECS计算型、通用型、内存型规格族属于独享型云服务器,在高负载不会出现计算资源争夺现象,因为每一个vCPU都对应一个Intel ® Xeon ®处理器核心的超线程,具有性能稳定且资源独享的特点。本文为大家整理汇总了阿里云服务器ECS计算型、通用型、内存型主要实例规格族具体实例规格有哪些,各个实例规格的性能特点和主要适用场景。
阿里云服务器计算型、通用型、内存型主要实例规格性能特点和适用场景汇总
|
9天前
|
存储 Java 程序员
结构体和类的内存管理方式在不同编程语言中的表现有何异同?
不同编程语言中结构体和类的内存管理方式既有相似之处,又有各自的特点。了解这些异同点有助于开发者在不同的编程语言中更有效地使用结构体和类来进行编程,合理地管理内存,提高程序的性能和可靠性。
17 3
|
11天前
|
存储 缓存 Java
结构体和类在内存管理方面的差异对程序性能有何影响?
【10月更文挑战第30天】结构体和类在内存管理方面的差异对程序性能有着重要的影响。在实际编程中,需要根据具体的应用场景和性能要求,合理地选择使用结构体或类,以优化程序的性能和内存使用效率。
|
11天前
|
存储 缓存 算法
结构体和类在内存管理方面有哪些具体差异?
【10月更文挑战第30天】结构体和类在内存管理方面的差异决定了它们在不同的应用场景下各有优劣。在实际编程中,需要根据具体的需求和性能要求来合理选择使用结构体还是类。
|
4月前
|
存储 缓存 安全
阿里云服务器实例规格选择参考:经济型、通用算力型、计算型、通用型、内存型区别
当我们在通过阿里云的各种活动选择云服务器实例规格的时候会发现,相同配置的云服务器往往有多个不同的实例可选,而且价格差别也比较大,这会是因为不同实例规格的由于采用的处理器不同,底层架构也有所不同(例如X86 计算架构与Arm 计算架构),因此不同实例的云服务器其性能与适用场景是有所不同。目前阿里云的活动中,主要的实例规格可分为经济型、通用算力型、计算型、通用型、内存型,对于很多初次接触阿里云服务器的用户来说,了解他们之间的差别就是比较重要的了,下面小编来为大家简单介绍下它们之间的区别。
阿里云服务器实例规格选择参考:经济型、通用算力型、计算型、通用型、内存型区别
|
3月前
|
存储 Go
Go 内存分配:结构体中的优化技巧
Go 内存分配:结构体中的优化技巧
|
5月前
|
弹性计算 安全 前端开发
云服务器ECS通用型、计算型和内存型区别以及详细介绍
阿里云ECS实例有计算型(c)、通用型(g)和内存型(r)系列,区别在于CPU内存比。计算型1:2,如2核4G;通用型1:4,如2核8G;内存型1:8,如2核16G。实例有第五代至第八代,如c7、g5、r8a等,新一代通常使用更先进的处理器。性能参数如CPU主频、IOPS和网络带宽随实例规格变化。实例适合场景包括高网络包收发、数据库、计算密集型任务等。
|
5月前
|
弹性计算 安全 前端开发
阿里云服务器ECS通用型、计算型和内存实例区别、CPU型号、性能参数表
阿里云ECS实例有计算型(c)、通用型(g)和内存型(r)系列,区别在于CPU内存比。计算型1:2,如2核4G;通用型1:4,如2核8G;内存型1:8,如2核16G。实例有第五代至第八代,如c7、g5、r8a等,每代CPU型号和主频提升。例如,c7使用Intel Ice Lake,g7支持虚拟化Enclave。实例性能参数包括网络带宽、收发包能力、IOPS等,适合不同场景,如视频处理、游戏、数据库等
150 0
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
366 0
|
22天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
44 1