内存对齐计算方法(偏移量)

简介: 内存对齐简单来讲就是把一个数据存放到内存中,其内存的地址要与数据自己大小为整数倍。 处理器在执行指令去操作内存中的数据,这些数据通过地址来获取。 当一个数据所在的地址和它的大小对齐的时候,就说这个数据对齐了,否则就是没对齐。

内存对齐简单来讲就是把一个数据存放到内存中,其内存的地址要与数据自己大小为整数倍。 处理器在执行指令去操作内存中的数据,这些数据通过地址来获取。 当一个数据所在的地址和它的大小对齐的时候,就说这个数据对齐了,否则就是没对齐。


内存对齐是以空间换时间的方法,计算机一次就可以把存储的数据提取出来,极大提高了效率。


首先以结构体为例来阐明是如何计算的。


结构体对齐规则:


1.1


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


1.2


其中对齐数=编译器默认的一个对齐数与该成员大小的较小值。(vs默认为8)


1.3


其他成员变量依次要按照对齐数的整数倍的地址处来存放。


1.4


结构体总体的大小要为最大对齐数的整倍数。(每一个成员变量都有自己的对齐数,与1.3描述的对象不一样)


1.5


如果一个结构体里面包含一个结构体,把其看作一个成员就行(但其整体对齐数不能看作一个对齐数来比是否为最大对齐数)。


简单看个例子:


#include <stdio.h>

struct s1

{

char a;

int b;

char c;

};

struct s2

{

char a;

char b;

int c;

};

struct s3

{

int c;

char a;

char b;

};

int main()

{

struct s1 q = { 0 };

struct s2 w = { 0 };

struct s3 e = { 0 };

printf("%d\n", sizeof(q));

printf("%d\n", sizeof(w));

printf("%d\n", sizeof(e));

return 0;

}


结果:


12

8

8

D:\VS\Project4\x64\Debug\Project4.exe (进程 13452)已退出,代码为 0。

按任意键关闭此窗口. . .

分析:


三个结构体其中包含的成员一样,但为什么打印的结果不一样呢?这就用到了内存对齐了。


先看s1在内存中真实的存储:


              a

               b

               b

               b

               b

               c

12刚好是最大对齐数4的整数倍,所以此处即为完整内存大小。


                 结束


注释:

1. char类型所占字节为1,比默认对齐数8要小,所以对齐数是1。


2. int类型所占字节为4,比默认对齐数8要小,所以对齐数是4。


3.所以最大对齐数就是4。


4. 而其他成员变量依次要按照对齐数的整数倍的地址处来存放。所以要往下偏移(浪费)3个节大小,再往下就是4,来存放int类型,存完int类型时为8,


5. 再来一个char类型,对齐数为1,所以现在内存大小为9,


6. 此外还要满足是最大对齐数的整数倍,所以还要再偏移(浪费)3个字节大小,即为12。


于是s2在内存中真实的存储:


                   a

                   b

                 

                    c

                    c

                    c

                    c


                  结束


注释:


1. 一个char类型,对齐数为1,所以存放在了0地址处,


2. 再来一个char类型,对齐数为1,所以现在内存大小为2,


3. 接下来是int类型,所以要往下偏移2个字节大小,再存放int的4个字节,


4. 现在内存大小为8,刚好是最大内存数4的整数倍。即为8。


5. 同理可得s3在内存中真实的存储情况,有兴趣的小伙伴可自行研究一下哈。


当结构体里面包含一个结构体呢?


如:


#include <stdio.h>

struct s1

{

char a;

   int  b;

char c;

};

struct s2

{

struct s1 s;

char a;

char b;

int c;

};

int main()

{

printf("%d\n", sizeof(s2));

return 0;

}


结果:


20

D:\VS\Project4\x64\Debug\Project4.exe (进程 9968)已退出,代码为 0。

按任意键关闭此窗口. . .

分析:


1. 先来排结构体s,一个char类型,一个int类型,在一个char类型。最大对齐数是4,所以最后结果是12。


2. 再来一个char类型,对齐数为1,直接在后面存就行,所以现在内存大小为13。


3. 再来一个char类型,内存大小变为14。


4. 因为最大对齐数为 4, 14 不是4的倍数,所以会往后偏移(浪费)2个字节大小,变为16,再来存放int的4个字节,即为20。


此外补充两个知识点:


一:


#pragma pack (4)


表示设置默认对齐数为4。


#pragma pack ()


表示取消设置的默认对齐数。


二:


offsetof 可计算偏移量大小。


size_t offsetof(struct name, nember name);


(成员相当于类型的偏移量)。

————————————————


目录
相关文章
|
6月前
|
Java 数据库连接
Java中的内存泄漏排查与预防方法
Java中的内存泄漏排查与预防方法
|
15天前
|
存储 安全 iOS开发
内存卡怎么格式化?6个格式化方法供你选
随着使用时间的增加,内存卡可能会因为数据积累、兼容性或是文件系统损坏等原因需要进行格式化。那么怎样正确格式化内存卡呢?格式化内存卡的时候需要注意什么呢?本文会给大家提供详细的步骤,帮助大家轻松完成格式化内存卡的操作。
|
2月前
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
191 52
|
6月前
|
存储 安全 数据库
阿里云服务器计算型、通用型、内存型主要实例规格性能特点和适用场景汇总
阿里云服务器ECS计算型、通用型、内存型规格族属于独享型云服务器,在高负载不会出现计算资源争夺现象,因为每一个vCPU都对应一个Intel ® Xeon ®处理器核心的超线程,具有性能稳定且资源独享的特点。本文为大家整理汇总了阿里云服务器ECS计算型、通用型、内存型主要实例规格族具体实例规格有哪些,各个实例规格的性能特点和主要适用场景。
阿里云服务器计算型、通用型、内存型主要实例规格性能特点和适用场景汇总
|
2月前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
71 6
|
6月前
|
缓存 算法 Java
Java面试题:深入探究Java内存模型与垃圾回收机制,Java中的引用类型在内存管理和垃圾回收中的作用,Java中的finalize方法及其在垃圾回收中的作用,哪种策略能够提高垃圾回收的效率
Java面试题:深入探究Java内存模型与垃圾回收机制,Java中的引用类型在内存管理和垃圾回收中的作用,Java中的finalize方法及其在垃圾回收中的作用,哪种策略能够提高垃圾回收的效率
51 1
|
3月前
|
机器学习/深度学习 算法 物联网
大模型进阶微调篇(一):以定制化3B模型为例,各种微调方法对比-选LoRA还是PPO,所需显存内存资源为多少?
本文介绍了两种大模型微调方法——LoRA(低秩适应)和PPO(近端策略优化)。LoRA通过引入低秩矩阵微调部分权重,适合资源受限环境,具有资源节省和训练速度快的优势,适用于监督学习和简单交互场景。PPO基于策略优化,适合需要用户交互反馈的场景,能够适应复杂反馈并动态调整策略,适用于强化学习和复杂用户交互。文章还对比了两者的资源消耗和适用数据规模,帮助读者根据具体需求选择最合适的微调策略。
995 5
|
3月前
|
缓存 监控 Java
在使用 Glide 加载 Gif 动画时避免内存泄漏的方法
【10月更文挑战第20天】在使用 Glide 加载 Gif 动画时,避免内存泄漏是非常重要的。通过及时取消加载请求、正确处理生命周期、使用弱引用、清理缓存和避免重复加载等方法,可以有效地避免内存泄漏问题。同时,定期进行监控和检测,确保应用的性能和稳定性。需要在实际开发中不断积累经验,根据具体情况灵活运用这些方法,以保障应用的良好运行。
|
6月前
|
存储 监控 安全
内存卡数据恢复,3个方法帮你找回丢失的照片和视频
今天,针对内存卡数据恢复,本期做一个详细的归纳,分析常见的数据丢失原因、详细的数据恢复步骤、以及如何保护内存卡数据。
内存卡数据恢复,3个方法帮你找回丢失的照片和视频
|
6月前
|
存储 缓存 安全
阿里云服务器实例规格选择参考:经济型、通用算力型、计算型、通用型、内存型区别
当我们在通过阿里云的各种活动选择云服务器实例规格的时候会发现,相同配置的云服务器往往有多个不同的实例可选,而且价格差别也比较大,这会是因为不同实例规格的由于采用的处理器不同,底层架构也有所不同(例如X86 计算架构与Arm 计算架构),因此不同实例的云服务器其性能与适用场景是有所不同。目前阿里云的活动中,主要的实例规格可分为经济型、通用算力型、计算型、通用型、内存型,对于很多初次接触阿里云服务器的用户来说,了解他们之间的差别就是比较重要的了,下面小编来为大家简单介绍下它们之间的区别。
阿里云服务器实例规格选择参考:经济型、通用算力型、计算型、通用型、内存型区别