怎么计算结构体的大小

引言

先看两个例子:

case1:

case2:

可以看到再计算结构体大小的时候,应为变量的位置不同,而导致得到的结构体大小不同,这是什么原因呢?本文将带你揭秘。

基本类型的大小

先来了解一下基本类型的大小吧

byte 1个字节
chart 2个字节
short 2个字节
int 4个字节
float 4个字节
long 8个字节
double 8个字节

三个原则:

首先我们需要了解三个原则,他是求解结构体大小问题的核心


1.结构体变量的首地址,必须是结构体 "最宽基本类型成员" 大小的整数倍(0被认为是任何数的整数倍)。  
2.结构体每个成员相对于结构体首地址的偏移量,都是该成员的整数倍
3.结构体的总大小,为结构体 “最宽基本类型成员” (将嵌套结构体里的基本类型也算上,得出的最宽基本类型) 大小的整数倍

//这三个原则都是为了服务一个约定  --  内存对齐

参考自:结构体大小如何计算?-CSDN博客

什么是内存对齐

元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每个元素放置到内存中时,它都会认为内存是按照自己的大小(通常它为4或8)来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始,这就是所谓的内存对齐。

// 注: 内存对齐也是可以人为干预的,我们将在文章最后给出解答

为什么要内存对齐:

  • 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
  • 硬件原因:经过内存对齐之后,CPU的内存访问速度大大提升
  • 性能原因:数据结构(尤其栈)应该尽可能地在自然边界上对齐。

实例解答

 回归主题,我们了解完三个原则后,内存对齐后,我们可以做下面的例子来进一步加深对结构体大小的理解

 揭秘引言case

case1:

struct test

{

  char c1;

  char c2;

  int n;

};

case2:

struct test

{

  char c1;

  char c2;

  int n;

};

 "最宽基本类型成员" 大小 是 int - 4 ,且结构体的大小是他的倍数

 

case1中c1 和 c2 只占一位,我们得到的最小大小是4,so后面来个空位就需要空出来,直到第五个格子,即下标是4的位置开始存入int 类型的 n

case2 中c1 后直接跟 n了,我们的n只能从下标4的位置开始存入,然后才再存c2,这样看的话,是不是觉得大小是4+4+1=9了? 大NO特NO,我们的三大原则第三条 -- 结构体的总大小,为结构体 “最宽基本类型成员” 大小的整数倍

如果包含数组呢?

包含数组的结构体

核心 --  数组是连续的内存空间,把数组看成连续存放的类型即可

struct test

{

  char arr[5];

  char c1;

  int n;

};

你觉得是多少?

最宽基本类型成员” 大小,是5吗?

不,是int -- 4

arr  和 c1 占了前面的8位,加上int的4位--大小就是 8+4=12

嵌套结构体的结构体呢?

嵌套结构体的结构体

struct test

{

  char c1;

  int n;

  char c2;

 struct testSon{

  char c3;

  int n2;

};

};

为什么是20呢?

其实这里只需要额外注意一点:外层结构体的c2 不和 内层的 c3共享4个连续内存空间

20 = 4(c1) + 4(n)+4(c2)+4(c3)+4(n2)

有的小伙伴已经忍不住要问,那联合体呢?

包含联合体的结构体:

核心 -- 联合体大小就是他的最大类型大小

struct test

{

  char c1;

  int n;

  char c2;

  union sizeof_Struct

  {

    char c3;

    int n2;

    double d;

  };

};

还是先找最大类型大小 -- double -- 8

则: 24=8(c1 + n)+8(c2)+8(联合体)

那么下面我们玩点骚的咯 -- 指定对齐值

指定对齐值

直接行例子:

16 = 4(c1) + 4(n) + (4+4)(c2) , 最大类型是double -8 >4 对齐值是4

24= 8 (c1)+ 8(n)+ 8(c2)  我们这里的最大类型大小   8<16,对齐值取8

注: 由于硬件需求,我们的指定对齐值一般要求是4的倍数

总结: 

对齐值取的是    min(指定值,最宽基本类型成员" 大小);

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-20 23:38:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-20 23:38:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-20 23:38:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-20 23:38:01       20 阅读

热门阅读

  1. 使用JWT、Redis + token实现用户登录的两种方式。

    2024-04-20 23:38:01       14 阅读
  2. Android 13 有线以太网静态ip保存逻辑梳理分析

    2024-04-20 23:38:01       14 阅读
  3. 使用Python实现超参数调优

    2024-04-20 23:38:01       14 阅读
  4. Swift知识点 --- AnyView

    2024-04-20 23:38:01       12 阅读
  5. hyref 开发者推荐项目

    2024-04-20 23:38:01       14 阅读
  6. React Flow浏览器默认事件失效问题解决

    2024-04-20 23:38:01       15 阅读
  7. npm 更改国内镜像的方法

    2024-04-20 23:38:01       14 阅读
  8. 等保测评:网络安全法规框架下的关键合规实践

    2024-04-20 23:38:01       14 阅读
  9. vue--样式绑定--样式切换方法

    2024-04-20 23:38:01       11 阅读
  10. Rust 构建跨平台 GUI 的新选择

    2024-04-20 23:38:01       12 阅读