如何计算结构体的大小?结构体内存对齐【C语言】

news/2024/11/8 0:35:29/

今天我们来讲讲结构体的大小如何来计算

其中涉及到一个结构体中的热门考点:结构体内存对齐

话不多说,开始学习!

要想计算结构体的大小,首先要了解结构体的对齐规则。

目录

结构体内存对齐规则

举例

为什么存在内存对齐?

如何修改默认对齐数?


结构体内存对齐规则

1、第一个成员在与结构体变量偏移量为0的地址处。

2、其他成员变量要对齐到对齐数的整数倍地址处。

        对齐数=编译器默认对齐数与该成员大小的较小值。

        VS中默认的值为8,Linux gcc无默认对齐数,其对齐数就是成员变量自身大小。

3、结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

4、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的成员中最大对齐数的整数倍处,结构            体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

举例

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

 22e22b4ccafd48248f853d5abc701b05.png

如图,内存中有一块空间放的是结构体s1,

        (1)对于第一个成员变量c1,它在与结构体变量偏移量为0的地址处(也就是图中的0),因为c1的类型是char(占一个字节),所以图中灰色的格子放的就是c1

        (2)接着,对于第二个成员变量 i 它的类型是int,为四个字节,又因为在VS中默认对齐数是8字节,4<8,所以,变量 i 的对齐数为4。因为要放到对齐数整数倍位置,所以 i 应该放在偏移量为4的位置,图中黄色格子放的就是 i 。

        (3)再然后,对于第三个成员变量c2,它的类型是char,大小为1字节,1<8, 所以c2的对齐数是1。因为要放到对齐数整数倍位置,所以c2可以放在偏移量为8的位置,图中红色格子放的是c2.

        (4)最后,因为结构体总大小为最大对齐数的整数倍。前面我们已知c1对齐数=1,i 对齐数=4,c2对齐数=1,所以,结构体的最大对齐数为4,所以结构体的最终大小应该对齐4的整数倍位置,即图中12的位置,所以,整个结构体大小为12.

结构体嵌套问题

struct s2
{char c1;struct s1 s1;double d;
}

若出现结构体嵌套问题,如上图

需先计算struct s1的最大对齐数,由第一个案例可知,结构体s1的最大对齐数是4,所以struct s1对齐到4的整数倍位置即可.

为什么存在内存对齐?

大部分参考资料是这么说的:

1、平台原因(移植原因)

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

2、性能原因:

        数据结构(尤其是栈)应该尽可能地在自然对齐边界上对齐。

原因在于,为了访问未对齐的内存,处理器需要做两次内存访问;而对齐的内存仅需要访问一次。

总体来说:结构体内存对齐是拿空间换时间的做法。

在设计结构体的时候,让占用空间小的成员尽量集中在一起,可以既满足对集,又节省空间。

如何修改默认对齐数?

结构体在对齐方式不合适的时候,我们可以修改默认对齐数。

如:

#pragma pack(4)//更改默认对齐数为4
struct s1
{char c1;int i;char c2;
};
#pragma pack()//还原为默认


http://www.ppmy.cn/news/11449.html

相关文章

Spring Boot 日志详解

Spring Boot 日志一、日志有什么用二、日志怎么用三、自定义日志打印3.1 在程序中得到日志对象3.2 使用日志对象打印日志四、日志级别4.1 日志级别有什么用4.2 日志级别的分类与使用4.3 日志级别设置五、日志持久化5.1 配置文件名5.2 配置保存路径六、更简单的日志输出 -- lomb…

python直接赋值、浅拷贝与深拷贝

本文主要参考这篇博文python浅拷贝与深拷贝 基本概念 首先了解python中的一些基本概念 变量&#xff1a;是一个系统表的元素&#xff0c;拥有指向对象的连接空间对象&#xff1a;被分配的一块内存&#xff0c;存储其所代表的值引用&#xff1a;是自动形成的从变量到对象的指…

118页4万字智慧检务大数据平台解决方案

【版权声明】本资料来源网络&#xff0c;知识分享&#xff0c;仅供个人学习&#xff0c;请勿商用。【侵删致歉】如有侵权请联系小编&#xff0c;将在收到信息后第一时间删除&#xff01;完整资料领取见文末&#xff0c;部分资料内容&#xff1a; 目录 第1章 前言 1.1、 政策背…

JAVA中的for循环使用方法

一. 循环结构1. 概念在学习Java里的循环之前&#xff0c;我们先来了解一下到底什么是循环&#xff0c;以及循环的作用。我们先来看下面这张图&#xff1a;大家想一下&#xff0c;我们在400米的跑道上参加万米长跑&#xff0c;正常情况下要跑25圈&#xff0c;这25圈每一圈的跑步…

数据结构基础——认识数据结构与算法

目录 &#x1f354;什么是数据结构&#xff1f; &#x1f32d;1.数据的逻辑结构 &#x1f32d;NUM 1 : 集合 &#x1f32d;NUM 2 : 线性结构 &#x1f32d;NUM 2 : 树形结构 &#x1f32d;NUM 4 :图结构&#xff08;网状结构&#xff09;…

nacos 2.1.0集群生产环境多节点部署

nacos 2.1.0集群生产环境多节点部署 版本 2.1.0版本发布日期 2022-04-29官网 集群部署说明GitHub GitHub - alibaba/nacos: an easy-to-use dynamic service discovery, configuration and service management platform for building cloud native applications. 下载地址&…

前端优化原理篇(生命周期)

1&#xff0c; 性能评估模型 对于前端的性能的评判 主要是以下四个方面&#xff1a; 2&#xff0c;性能测量工具 1&#xff0c;浏览器的performarce功能 指路可看链接 2&#xff0c;lighthouse工具 3&#xff0c;生命周期 网站 页面的整个生命周期&#xff0c;通俗的讲&a…

《回眸2022·圆满收官||展望2023·砥砺奋发》

系列文章目录 文章目录系列文章目录寄言和CSDN相遇大学生活从小白到千粉博主回眸2022|圆满收官展望2023|砥砺奋发致每一个追梦人寄言 岁月不距&#xff0c;时节如流&#xff01;站在岁末的门槛前&#xff0c;回望2022这一年&#xff0c;不知你是否已经完美的书写完2022的答卷&…