当前位置: 首页 > news >正文

struct结构体内存对齐详解

一,什么是内存对齐

1. 即在 计算 一个 结构体对象的 大小的时候 ,其内部成员 占用大小 比 原本类型所占用  的 空间要大 --- 会按照额外的 内存对齐 规则 多占用空间 。

2.现象:

如下图:A 的 成员 一个字符型 (1字节) + 一个int整形(4字节), 按照预想应该是 5字节,但是实际结果却是 8 字节。

二 ,解释(具体对齐规则)

1. 内存对齐数

        要正确计算结构体 总大小,首先要了解 内存对齐数 -- 一个结构体的内存对齐数 由其 成员决定,每一个成员都有自己的内存对齐数(如果是基本类型,内存对齐数是本身大小),结构体的内存对齐数为 其内部成员中最大的内存对齐数 。

如 :struct B{ char c; int a;} 中 结构体 B的内存对齐数为 4 (c 的 内存对齐数 1 < a 的内存对齐数4 )

若 内部包含 结构体 成员 呢 ?
如 :struct B{ char c; int a;}       struct C{char c;struct B b;}

        结构体 C的内存对齐数为 4   ( c 的 内存对齐数 1 < b 的内存对齐数 4 ) 

2. 开始实际计算

        知道一个 结构体的内存对齐数 后 ,便可以开始计算 结构 体 的大小

        计算规则就是 ,按成员 声明的顺序开始计算 :保证每个成员 都 在 自己内存对齐数 倍数位置处 开始占用内存 。如下图 

例一:

struct A
{//			 空间占用		 对齐数char c;      // 0 -- 123	   1		(在第0位置处开始占用, 从 1 位置处开始补齐三个字节 ,使 a 能够在 第 4 位置处开始占用 )int a;	     // 4 5 6 7	       4		(在第 4 位置处开始占用,正常占用 4 个 字节)char c1;     // 8			   1		(在第 8 位置处开始占用,正常占用 1 个 字节)char c2;	 // 9			   1        (在第 9 位置处开始占用,正常占用 1 个 字节)char c3;	 // 10 -- 11	   1        (在第10位置处开始占用, 从 11位置处开始补齐 1 个字节 使 b 能够在第 12 位置处开始占用)int b;		 // 12 13 14 15    4        (在第 12 位置处开始占用,正常占用 4 个 字节)//				b2对齐数 4	int b2;	     // 16 17 18 19   -- 20 21 22 23   (在第16位置处开始占用, 从 20位置处开始补齐 4 个字节 使 d 能够在第 24 位置处开始占用)//				d 对齐数 8double d;    // 24 25 26 27 28 29 30 31	       (在第 24 位置处开始占用,正常占用 8 个 字节)
};
int main()
{printf("%d\n", sizeof(struct A));return 0;
}

例二 :

(注 : 结构体的内存对齐数为 其内部成员中最大的内存对齐数  )

struct A
{//			 空间占用		 对齐数char c;      // 0 -- 123	   1		(在第0位置处开始占用, 从 1 位置处开始补齐三个字节 ,使 a 能够在 第 4 位置处开始占用 )int a;	     // 4 5 6 7	       4		(在第 4 位置处开始占用,正常占用 4 个 字节)char c1;     // 8			   1		(在第 8 位置处开始占用,正常占用 1 个 字节)char c2;	 // 9			   1        (在第 9 位置处开始占用,正常占用 1 个 字节)char c3;	 // 10 -- 11	   1        (在第10位置处开始占用, 从 11位置处开始补齐 1 个字节 使 b 能够在第 12 位置处开始占用)int b;		 // 12 13 14 15    4        (在第 12 位置处开始占用,正常占用 4 个 字节)//				b2对齐数 4	int b2;	     // 16 17 18 19   -- 20 21 22 23   (在第16位置处开始占用, 从 20位置处开始补齐 4 个字节 使 d 能够在第 24 位置处开始占用)//				d 对齐数 8double d;    // 24 25 26 27 28 29 30 31	       (在第 24 位置处开始占用,正常占用 8 个 字节)
};
struct B
{//				空间占用				对齐数int a;       // 0 1 2 3					   4		(在第0位置处开始占用)char c;		 // 4 -- 5					   1		(在第4位置处开始占用, 从 5 位置处开始补齐 1 个字节 使 d 能够在第 6 位置处开始占用)short b;	 // 6 7						   2		(在第6位置处开始占用)struct A ad; // 8 .. 39                    8		(在第8位置处开始占用)
};
int main()
{printf("%d\n", sizeof(struct A));printf("%d\n", sizeof(struct B));return 0;
}

例三:

注意 : 最终结构体 的大小 要在满足所有结构体成员对齐的情况下,还要是 结构体成员内存对齐数 的 最大值 的倍数 (这里 就是 4 的 倍数 ,所以 总占用为 5+3(补) = 8

struct A									// 对齐数      空间占用 
{															int a;									//   4	       0 1 2 3			(从0位置开始占用 4 个字节)char c;									//   1            1              (从 1 位置开始占用 1 个字节)// 但是最终结构体 的大小 要为 结构体成员内存对齐数 的 最大值 的倍数 (这里 就是 4 的 倍数 ,所以 总占用为 5+3(补) = 8
};
int main()
{printf("%d\n", sizeof (struct A));return 0;
}


文章转载自:

http://Gc6CkYgx.trsdm.cn
http://k7AyL9lh.trsdm.cn
http://l7sZ1ePW.trsdm.cn
http://zdEze8YH.trsdm.cn
http://PLq9IYjF.trsdm.cn
http://NlRXyF2m.trsdm.cn
http://U8DwuGSa.trsdm.cn
http://ynCtHi2J.trsdm.cn
http://nDkUQysH.trsdm.cn
http://wBou6RDw.trsdm.cn
http://QaLq2dR9.trsdm.cn
http://LTuyc7uW.trsdm.cn
http://Pqjg0MNT.trsdm.cn
http://qMfXBxUT.trsdm.cn
http://f3AYcpa8.trsdm.cn
http://GLpIgCfc.trsdm.cn
http://97f6xSkB.trsdm.cn
http://Sd7DPfWc.trsdm.cn
http://WPyKNkZy.trsdm.cn
http://F5sDMBje.trsdm.cn
http://EVMdrBss.trsdm.cn
http://yMG2qYuV.trsdm.cn
http://a94ZtPIE.trsdm.cn
http://UGbCSUqq.trsdm.cn
http://kRKJcSsi.trsdm.cn
http://8Uz5tf3G.trsdm.cn
http://UGcQyMwB.trsdm.cn
http://DHZIsuKF.trsdm.cn
http://aAVSPg2w.trsdm.cn
http://74zUVd6j.trsdm.cn
http://www.dtcms.com/a/372490.html

相关文章:

  • 使用QLoRA 量化低秩适配微调大模型介绍篇
  • 变量与常量
  • 第7.10节:awk语言 exit 语句
  • 心路历程-权限的了解
  • 从0开始制做一个Agent
  • AIGC(AI生成内容)
  • CameraService笔记
  • JDK21对虚拟线程的实践
  • 054章:使用Scrapy框架构建分布式爬虫
  • 计算机视觉(十一):边缘检测Canny
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘wheel’问题
  • 监控系统 | 脚本案例
  • TI-92 Plus计算器:高等数学之函数特性判断
  • IDEA 配置tomcat服务器
  • HTTP中Payload的含义解析
  • docker-compose build命令及参数
  • 接入第三方升级协议OTA教程
  • IO模型多路转接
  • Python-基础语法
  • FastApi框架
  • 单片机的bin、exe、elf、hex文件差异
  • 基于ResNet50的智能垃圾分类系统
  • 大模型推理参数讲解
  • Linux 性能调优之 OOM Killer 的认知与观测
  • Linux->日志的实现
  • 西门子 S7-200 SMART PLC :3 台电机顺启逆停控制(上篇)
  • SAP系统两种部署方式:公有云VS私有云 企业如何选择?
  • 用博图FB类比c#中sdk的api
  • 8.渗透-.虚拟机安装
  • Redis基础(含常用命令等以快速入门)