结构体内存对齐

news2024/11/13 13:01:17

     在知道了结构体类型的基本使用之后,我们需要深入探讨一个问题,即计算结构体的大小,这也是一个热门的考点:结构体内存对齐。

目录

一、结构体的对齐规则

二、例题

2.1 例题一

 2.2 例题二

2.3 例题三

 ​编辑

三、为什么存在内存对齐?

3.1 平台原因:

3.2 性能原因:

四、结构体成员变量的建议

五、修改默认对齐数

一、结构体的对齐规则

     所以结构体在内存中到底是怎么开辟空间的?实际上结构体在内存中开辟空间有以下几点对齐规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处。
  2. 其他的成员变量要对齐到某个【对齐数】的整数倍的偏移处。【对齐数】:结构体成员自身大小和编译器默认对齐数的较小值,在vs中默认对齐数是8.
  3. 结构体的总大小,必须是最大对齐数的整数倍,每个结构体变量都有一个对齐数,其中最大的对齐数就是最大对齐数。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

二、例题

     在下面的例题中,我们直接使用结构体的对齐规则来做。

2.1 例题一

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

int main()
{
	struct S2 s2;
	printf("%d\n", sizeof(struct S2));
	return 0;
}

问题分析:
 

 2.2 例题二

struct S3
{
	double d;
	char c;
	int i;
};

int main()
{
	struct S3 s3;
	printf("%d\n", sizeof(struct S3));
	return 0;
}

 

问题分析:
 

2.3 例题三

struct S3
{
	double d;
	char c;
	int i;
};
struct S4
{
	char c1;
	struct S3 s3;
	double d;
};

int main()
{
	struct S4 s4;
	printf("%d\n", sizeof(struct S4));
}

 

问题分析:

 

三、为什么存在内存对齐?

3.1 平台原因:

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

3.2 性能原因:

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

例如:假设32位机器CPU读取时一次读4个字节,

总体来说:

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

四、结构体成员变量的建议

     在设计结构体的时候,我们既要满足对齐,又要节省空间,这时候我们想到让占用空间小的成员尽量集中在一起的方式。

例如:

struct s1
{
	char c1;
	int i;
	char c2;
};   //结构体的大小是12个字节

struct s2
{
	char c1;
	char c2;
	int i;
};    //结构体的大小是8个字节

五、修改默认对齐数

     在上面求结构体的大小时,对齐数使用的很多,在vs编译环境下,默认对齐数是8,但是对于默认对齐数我们也是可以进行修改的。

    之前我们见过了 #pragma 这个预处理指令,这里我们再次使用,可以改变我们的默认对齐数。

#pragma pack(1)   //设置默认对齐数是1
struct S2
{
	char c1;
	int i;
	char c2;
};
#pragma pack()  //取消设置的默认对齐数,还原为默认
结构在对齐方式不合适的时候,我么可以自己更改默认对齐数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2082.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】vector,list迭代器失效

1.vector迭代器失效 vector容器的物理基础是线性表,底层是指针变量实现的。 在这里导致vector迭代器失效的原因会有两种-----插入失效,删除失效。 1.2插入数值导致迭代器失效 1.21扩容导致迭代器失效 我们在一块vector空间插入pos(20&…

第三章 单向链表的讲解与实现

初阶数据结构 第一章 时间复杂度和空间复杂度 第二章 动态顺序表的实现 第三章 单向链表的讲解与实现 文章目录初阶数据结构前言一、什么是链表?二、节点的定义:三、单向链表接口函数1、打印:2、尾插:3、头插:4、尾删…

改进YOLOv7系列: 最新结合用于小目标的新CNN卷积构建块

💡统一使用 YOLOv7 代码框架,结合不同模块来构建不同的YOLO目标检测模型。🌟本项目包含大量的改进方式,降低改进难度,改进点包含【Backbone特征主干】、【Neck特征融合】、【Head检测头】、【注意力机制】、【IoU损失函数】、【NMS】、【Loss…

Linux-进程控制

进程控制进程创建fork函数写时拷贝fork常规用法fork调用失败的原因进程终止进程等待进程程序替换程序替换的原理如何程序替换进程创建 fork函数 fork之前父进程独立运行,fork之后,父子两个执行流分别执行。 进程具有独立性,代码和数据必须独立…

机器学习HMM模型

目录1 马尔科夫链1.1 简介1.2 经典举例1.3 小结2 HMM简介2.1 简单案例2.2 案例进阶2.2.1 问题阐述2.2.2 问题解决3 HMM模型基础3.1 什么样的问题需要HMM模型3.2 HMM模型的定义3.3 一个HMM模型实例3.4 HMM观测序列的生成3.5 HMM模型的三个基本问题4 前向后向算法评估观察序列概率…

计算机毕业设计-SSM高校社团招新系统-JavaWeb大学生社团管理系统-源码+文档+讲解

注意:该项目只展示部分功能,如需了解,评论区咨询即可。 本文目录1.开发环境2.系统的设计背景3 前后台功能设计3.1 前台功能3.2 后台功能4 系统页面展示4.1 学生功能模块展示4.2 干部功能模块展示4.3 管理员功能模块展示5 更多推荐6 部分功能代…

如何用IDEA提高你的开发效率

前言 ​ 作为一名java开发工程师,IDEA无疑是我日常接触最多的工具。因此,能否高效使用IDEA软件,一定程度上决定了我们的开发效率。本文将主要介绍IDEA中的四个便于提高开发效率的功能,常用快捷键、实时模版、后缀补全、文件和代码…

《本地计算机DNS缓存文件》

C:\Windows\System32\drivers\etc 36.152.44.95 www.baidu.com 正常访问www.baidu.com可以DNS抓包,将百度的IP及域名加入文件位置的hosts文件中即该IP和域名将不再请求网络上的DNS服务器,即加快域名解析; 具体作用: 1.加快域名解…

什么是RPC框架?

什么是RPC? In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network), which is coded as if it wer…

创新能力 | 产品经理实践中常犯的七大错误

做产品是一个既感性又理性的过程,纵然有很多前辈同行的经验传承和技巧指导,但在落到实处是时,总难免犯一些错误。有些是经验不足导致,有些则是产品经理对于人性的浅见寡闻。本文作为产品经理实践指南专题的中级篇,阐述…

用 AWTK 和 AWPLC 快速开发嵌入式应用程序 (2)-走马灯

AWPLC 目前还处于开发阶段的早期,写这个系列文章的目的,除了用来验证目前所做的工作外,还希望得到大家的指点和反馈。如果您有任何疑问和建议,请在评论区留言。 1. 背景 AWTK 全称 Toolkit AnyWhere,是 ZLG 开发的开源…

全球名校AI课程库(35)| 辛辛那提大学 · 微积分Ⅱ课程『MATH101 Calculus II』

🏆 课程学习中心 | 🚧 CS数学基础课程合辑 | 🌍 课程主页 | 📺 中英字幕视频 | 🚀 项目代码解析 课程介绍 Trefor Bazett 教授在 Cincinnati 大学任教时,制作了两套完整的的数学课程(微积分、离…

Eclipse创建Servlet项目-7

目录 1、创建动态 Web 项目 2、使用 Eclipse 创建 Servlet 3、配置 web.xml 4、部署项目并启动服务器 通过前面的学习,我们了解了如何在 Tomcat 目录下手动部署 Servlet,这种方式不但效率低下,而且容易出错。因此,在实际开发中…

变量常量,基本数据类型及数据类型转换

⭐️ 变量常量与基本数据类型及数据类型转换 📍 来自:中南林业科技大学软件协会学术部:谢添 ⏲ 时间:2022 - 10 - 29 至 2022 - 10 - 30 🏠 官网:https://www.csuftsap.cn/ ✏️ 本章所有提供代码均已测…

四旋翼无人机学习第4节--STM32、MPU9250等器件的绘制

0 前言 当画stm32、mpu9250这种多引脚的芯片,就需要参考芯片手册啦。 这里给大家推荐一个芯片手册查询网站。 半导小芯-芯片查询工具 进入网站,输入芯片的具体名称,点击查询即可。 最后点击下载即可。 1 stm32芯片手册引脚查询 选择引脚…

学习在Git项目中使用子模块(图文教程)

一般认为 父项目 是当前正在做的主要工作,但需要依赖 子模块 中提供的算法或者工具。父项目 与 子模块 不是同一批人维护的,或者是需要分开维护的。 此情此景,需要学习该教程了!!! 文章目录1 如何在父项目…

基于Java的一个可自由拖拽的BI可视化系统(附源码)

介绍 这是一个可自由拖拽的BI可视化系统支持主流的关系数据:MySQL,Oracle,PostgreSQL等同时支持Apache Doris,这个一开始初衷就是为了 Doris 数据可视化分析做的后端框架使用了若依 功能 按项目管理数据看板看板具备分享功能可以…

每天五分钟机器学习:超平面分离定理和凸优化

凸集和凸函数 在点集拓扑学与欧几里得空间中,凸集是一个点集,其中每两点之间的直线上的点都落在该点集中。如下所示: 函数任意两点(x,f(x))和(y,f(y))连线上的值大于(x,y)区间内任意一点m的值f(m),那么这个函数就是一个凸函数: 超平面分离定理 空间中存在两类样本,…

【CV】第 3 章:使用 OpenCV 和 CNN 进行面部检测

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

JavaScript语法知识笔记(一)——书写方式,输入出语句,变量,字面量,标识符,数据类型。

01.JS的三种书写方式 <!-- 2.内嵌式的js --><script>// alert(sajmo);</script><!-- 3.外部js script 双标签 --><script src"script.js"></script> <!-- JS代码需要写到script标签中 --><script type"text/jav…