自定义类型结构体(中)

news2024/11/23 22:51:49

目录

  • 结构体内存对齐
    • 对齐规则
      • 例子一
      • 练习3
      • 练习4-结构体嵌套问题
    • 为什么存在内存对齐
      • 平台原因(移植原因)
      • 性能原因
    • 修改默认对齐数

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐓🏀 python

结构体内存对齐

对齐规则

首先得掌握结构体的对齐规则:
1.结构体的第一个成员对齐到相对结构体变量起始位置偏移量为0的地址处

2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处

对齐数=编译器默认的⼀个对齐数与该成员变量大小的较小值
VS中默认的值为8
Linux中没有默认对齐数,对齐数就是成员自身的大小

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

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

例子一

struct S1
{
	char c1;
	int i;
	char c2;
};
printf("%d\n", sizeof(struct S1));
struct S2
{
	char c1;
	char c2;
	int i;
};
printf("%d\n", sizeof(struct S2));

在这里插入图片描述

我们可以看到两个结构体内部的变量类型都是相同的,唯一区别就是内部的顺序不同,按理说内存大小都是相等才对,可是我们发现结果一个是12一个是8,其实这就是因为对齐规则所导致的

为了理解对齐规则具体是怎么回事我们需要用到一个宏为offsetof(可以直接用),这是计算结构体成员相较于起始位置的偏移量
offsetof的用法如下
在这里插入图片描述
offsetof的头文件为stddef.h
在这里插入图片描述
我们可以看到输出的结果为0 4 8

说明第一个成员的偏移量为0(相对于起始位置为0),第二个成员的偏移量为4(相对于起始位置为4),第三个成员的偏移量为8(相对于起始位置为8)

由于当中int为成员变量的最大值,但与VS最大的对齐数相比int要小一点,所以最后的结果是int(4)的倍数,所以会浪费一下内存空间

在这里插入图片描述
我们再来看另外一个
在这里插入图片描述
在这里插入图片描述

因为c1为灰色方块偏移量是0,c2为深红色方块偏移量是1,i为红色方框偏移量为4

由于成员变量要对齐到某个数字(对齐数)的整数倍的地址处,且对齐数=编译器默认的⼀个对齐数与该成员变量大小的较小值

因此c2的大小为1,所以对齐数就是1,所以i的对齐数就是4,因为中间有一些内存i并没有用到,所以那些内存(也就是绿色)被浪费了

最后因为结构体总大小为最大对齐数的整数倍,也就是i的大小4,因此8正好就是4的倍数

练习3

//练习3
struct S3
{
	double d;
	char c;
	int i;
};
printf("%d\n", sizeof(struct S3));

在这里插入图片描述
在这里插入图片描述
同样的double d的大小为8刚好和VS默认对齐数相同,所以对齐数是8,所以灰色方块就是d

char c的大小为1,1比8小,所以对齐数为1,红色方块就是c

int i的大小是4,4比8小,所以对齐数就是4,12是4的倍数,所以就从12开始,红色方块的就是i

绿色的就是浪费的内存

练习4-结构体嵌套问题

struct S4
{
char c1;
struct S3 s3;
double d;
};
printf("%d\n", sizeof(struct S4));

在这里插入图片描述
在这里插入图片描述
这道题重点就在于struct S3,我们回顾前面所写的
在这里插入图片描述
嵌套的结构体成员对齐到自己的成员中最大的对齐数的整数倍处,这里自己的成员其实就是struct S3的成员 double d(大小8), char c(大小1) ,int i(大小4),注意是自己的成员中最大的对齐数所以最大的对齐数就是double d(8)

为什么存在内存对齐

平台原因(移植原因)

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

性能原因

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

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

假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对齐成8的倍数,那么就可以用一个内存操作来读或者写值了。

否则,我们可能需要执行两次内存访问,因为对象可能被分放在两个8字节内存块中

我们再来举一个例子

我们知道32位机器上读取的数据是一次32位,所以每次都是固定读取32位的
如果我们没有对齐数的话就如下图
在这里插入图片描述
我们需要读取i的数据,这样的话我们可能会读取两次,导致效率会比较慢

而如果我们采用对齐的方式来读取的话就如下图
在这里插入图片描述
虽然c 和 i之间可能会浪费一些内存,但我们在读取的时候就可以做到一次性读完i的数据,这样效率就比较高

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

那在设计结构体的时候,我们既要满足对齐,又要节省空间,应该如何做到

其实我们只需要让占用空间小的成员尽量集中在一起

//例如:
struct S1
{
	char c1;
	int i;
	char c2;
};

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

S1 和 S2 类型的成员一模一样,但是 S1 和 S2 所占空间的大小有了一些区别
S2中两个char类型集中在一起就可能会把中间浪费的空间利用起来

修改默认对齐数

#pragma 这个预处理指令,可以改变编译器的默认对齐数

#include <stdio.h>
#pragma pack(1)//设置默认对⻬数为1
struct S
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对⻬数,还原为默认
int main()
{
	printf("%d\n", sizeof(struct S));
	return 0;
}

在这里插入图片描述
一般修改的默认对齐数都是2的倍数

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

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

相关文章

【LeetCode】每日一题 2023_11_2 环和杆(题目质量不错)

文章目录 刷题前唠嗑题目&#xff1a;环和杆题目描述代码与解题思路看看别人的题解 结语 刷题前唠嗑 今天是简单&#xff0c;我快乐了 题目&#xff1a;环和杆 题目链接&#xff1a;2103. 环和杆 题目描述 代码与解题思路 func countPoints(rings string) (ans int) {num…

OpenCV4(C++)——形态学(腐蚀、膨胀)

文章目录 一、腐蚀&#xff08;erode&#xff09;二、膨胀&#xff08;dilate&#xff09;三、形态学操作四、总结 一、腐蚀&#xff08;erode&#xff09; OpenCV 4提供了用于图像腐蚀的erode()函数。 void cv::erode(src, dst, kernel, anchor, iterations, borderType, bo…

【原创】java+swing+mysql校园论坛管理系统设计与实现

摘要&#xff1a; 随着互联网技术的不断发展&#xff0c;论坛作为一种信息交流和互动的平台&#xff0c;在学校中发挥着越来越重要的作用。校园论坛管理系统是为了方便学校管理论坛、提高论坛的互动性和用户体验而设计的一款系统。一般的论坛网站都是B/S架构&#xff0c;也就是…

NuGet 包私有源部署与创建 NuGet 包创建

一、前言 作为软件研发从业人员&#xff0c;在学习和工作中经常会遇到一些频繁需要的接口或者方法&#xff0c;总不能每次都是重新反复去实现它&#xff0c;更多的是需要随着学习和工作时间的积累&#xff0c;慢慢积攒自己的 类库 或者程序 NuGet 包&#xff0c;这有助于我们技…

引领制造业高质量发展,龙讯旷腾特邀出席2023工业软件生态大会

2023工业软件生态大会 为集中展示“新一代工业软件体系”、“新型产业数字化转型范式”&#xff0c;广东省工业和信息化厅、广东省科学技术厅、广东省教育厅及深圳市人民政府拟于2023年11月5日至6日在深圳市举办2023工业软件生态大会&#xff0c;由广东省数字化学会、电子五所…

关于栈内存的一些总结

我们日常使用的电脑内存一般是小端序&#xff0c;也就是从低地址到高地址。 一般来说栈向下增长。 但是这个方向不是确定的&#xff1a; 在小端序操作系统中&#xff0c;栈和堆的增长方向通常是与特定架构和操作系统相关的&#xff0c;因此不是唯一确定的。 小端序指的是将…

CV计算机视觉每日开源代码Paper with code速览-2023.10.31

精华置顶 墙裂推荐&#xff01;小白如何1个月系统学习CV核心知识&#xff1a;链接 点击CV计算机视觉&#xff0c;关注更多CV干货 论文已打包&#xff0c;点击进入—>下载界面 点击加入—>CV计算机视觉交流群 1.【基础网络架构】&#xff08;NeurIPS2023&#xff09;Fa…

【源码分析系列】antdv table滚动时固定表头

背景 当页面滚动的时候&#xff0c;如果超过表格的部分&#xff0c;表格的头部会固定在某个位置&#xff0c;方便用户看到数据栏的标。项目采用的是vue2antdv&#xff0c;但是这个版本的table没有sticky属性&#xff0c;所以需要自行解决。 滚动前&#xff1a; 滚动后&#x…

WoShop多语言外贸跨境商城源码(支持直接铺货,多语言,多货币切换)

多语言外贸跨境商城源码是一种用于构建多语言跨境电子商务平台的软件解决方案。这种源码通常支持多种语言&#xff0c;以便让商家能够轻松地将他们的产品和服务销售到全球各地。 以下是多语言外贸跨境商城源码的一些主要特点&#xff1a; 1. 多语言支持&#xff1a;源码通常支持…

类百度知识付费网站

需购买&#xff1a;部署联系&#xff0c;支持压缩包&#xff0c;doc&#xff0c;pdf预览等

什么?前端又出新轮子了?ofa.js

不需要打包的 MVVM JavaScript 框架 无需繁琐学习&#xff0c;无需 npm、nodejs、webpack&#xff0c;即刻上手 <script src"https://cdn.jsdelivr.net/gh/kirakiray/ofa.js/dist/ofa.min.js"></script>官方文档 取代 jQuery 在许多小型项目中&#x…

研发效能DevOps: Git安装

目录 一、理论 1.Git 2.Git 工具 二、实验 1.Git安装 2.配置Git 3. VS Code加载Git 一、理论 1.Git &#xff08;1&#xff09;简介 Git 是一个分布式版本控制及源代码管理工具;Git 可以为你的项目保存若干快照&#xff0c;以此来对整个项目进行版本管理。 Git 是一个…

clusterprolifer go kegg msigdbr 富集分析应该使用哪个数据集,GO?KEGG?Hallmark?

关注微信&#xff1a;生信小博士 5 Overview of enrichment analysis Chapter 5 Overview of enrichment analysis | Biomedical Knowledge Mining using GOSemSim and clusterProfiler 5.1.2 Gene Ontology (GO) Gene Ontology defines concepts/classes used to describ…

毕业生求职,需要做哪些准备工作?

第一、了解企业招聘需求&#xff0c;不同岗位除了对应的专业知识以为&#xff0c;还需要了解岗位的特点&#xff0c;比如&#xff1a;销售类型的工作&#xff0c;口才要好&#xff0c;逻辑要强。如果你懂技术&#xff0c;但是羞于表达&#xff0c;都是无法胜任的。结合自身性格…

ztree调整节点间距及一般使用

1.基本介绍 树形结构菜单的功能属于非常常见的一种菜单交互&#xff0c;本人先后也使用过多种树形结构的插件&#xff0c;有 ztree、xloadtree、treeview、datagrid-tree 等等等等。近期有个功能恰好又要使用tree菜单了&#xff0c;由于可自行选择使用的组件&#xff0c;所以略…

简单工厂模式、工厂方法模式、抽象工厂模式

简介 将实例化代码提取出来&#xff0c;放到一个类中统一管理和维护&#xff0c;达到和主项目依赖关系的解耦&#xff0c;从而提高项目的扩展性和维护性。 工厂模式将复杂的对象创建工作隐藏起来&#xff0c;而仅仅暴露出一个接口供客户使用&#xff0c;具体的创建工作由工厂管…

Axie Infinity 超级任务远超预期,和 YGG 一起探索 Web3 增长新方式!

参与超级任务的实际人数是预期人数的两倍。 超级任务将新玩家引入 Web3 游戏领域&#xff0c;并向他们介绍可以为其玩家旅程提供支持的社区。 Axie Infinity 超级任务旨在向新手和 Axie Classic 老 玩家介绍「Axie Infinity&#xff5c;起源」这款游戏。 整个活动共吸引了 4,…

Luminar Neo Mac/Windows中文版:引领AI图像编辑的革命性时代

Luminar Neo运用先进的AI技术&#xff0c;能够自动化地完成许多繁琐的编辑任务&#xff0c;如色彩校正、噪点消除、人脸识别等。这不仅大大提高了工作效率&#xff0c;同时也降低了对专业知识和技能的要求。无论你是专业摄影师&#xff0c;还是摄影爱好者&#xff0c;甚至是一个…

python写爱心代码【爱心代码编程python可复制粘贴】

python写爱心代码【爱心代码编程python可复制粘贴】 python程序代码&#xff1a;heart.py from math import cos, pi import numpy as np import cv2 import os, glob class HeartSignal: def __init__(self, curve"heart", title"Love U", frame_n…

程序员用接单平台靠谱吗?浅谈一下十年程序员的看法

后疫情时代&#xff0c;经济下行&#xff0c;这年头社会上就业也越来越卷了&#xff0c;程序员人才市场也日趋饱和。不少人嗅到危险气息&#xff0c;已经开始谋求出路了! 咱们程序员的话&#xff0c;“兼职”"接单"也不是个新鲜的话题了。养家糊口也好、财富自由也罢…