【c/c++】内存对齐
前言
首先我们要知道什么是内存对齐?
答:内存对齐(Memory Alignment)是计算机科学中的一个概念,指的是将数据存储在特定的内存地址上,以提高系统性能,是计算机存储数据的一种规则。
一、内存对齐的优点
在计算机内存中,数据存储的基本单位是字节。为了提高CPU对内存访问效率,数据(如结构体、类的成员变量等)在内存中的存储地址有一定规则,这种规则带来了,以下好处:
1、提高访问速度
-
CPU按字长(如在32位下CPU一次可以处理的字长是4字节,在64位下CPU一次可以处理的字长是8字节)来读取内存。如果数据是内存对齐的,处理器可以用一次内存访问操作就能读取完整的数据。
-
比如,一个32位处理器读取一个4字节的 int 型数据,若内存对齐,数据起始地址是4的倍数,处理器一次就能读取这个数据;如果没有对齐,可能需要多次访问才能获取全部数据,降低了访问速度。
2、便于移植和兼容 -
不同的硬件平台对数据存储的要求有所差异。符合内存对齐规则的数据结构可以更容易地在不同的硬件平台之间移植。
-
例如,在一个平台上编写的程序,数据是按照内存对齐方式存储的,当将程序移植到另一个兼容内存对齐的平台时,程序能够正确、高效地运行。
二、内存对齐规则
接下来的测试,都是在64位机器下进行的!!!
在C/C++中,结构体是一种复合数据类型,可以包含多个不同类型的成员,并且结构体占用的空间是连续的,成员在内存中按声明顺序排列的,他可以很好的向我们展示出内存对齐规则,接下来我们就以下面简单程序进行演示:
#include<stdio.h>
struct st {
int a; ----4字节
char b; ----1字节
short c; ----2字节
char d; ----1字节
double e; ----8字节
};
int main()
{
struct st a;
printf("%d\n", sizeof(a));
return 0;
}
我们来计算一下,上面定义结构体的大小:4+1+2+1+8=16字节,当我们执行程序对他进行运算时,执行结果为:
这是为什么呢?
这就是因为编译器和硬件对结构体内的数据进行了内存对齐,内存对齐规则要求:
1、分配内存的顺序是按声明顺序
2、每个变量相对于起始位置的偏移量必须是该变量类型大小的整数倍,不是整数倍就填充空字节,直到偏移量是整数倍为止。
3、最后整个结构体的大小必须是里面变量类型最大值的整数倍。
偏移量:当我们实例化一个结构体时,系统会给我们分配一块空间,而偏移量就是指,在分配的这块空间中的某个位置,相对于这块空间起始位置的距离(字节)。
根据对齐规则1、2条,则上面的结构体在内存中存储的,情况是:存储变量a从偏移量为零处开始,占四个字节,变量a内存后面偏移量为4而变量b为1字节可以整除,存入变量b,变量b内存后的偏移量为5,变量c为2个字节大小,不能整除,则填充一字节至偏移量为6的位置,可以整除存入变量c,变量c内存后的偏移量为8可以整除,存入变量d,变量d后的内存偏移量为9,变量e为8字节大小不可整除,填充至偏移量为16处,填入变量e,变量e的内存后偏移量为24,至此所以数据全部填入,此时所占内存为24字节,变量类型最大值为8,则满足规则3。
使用 #pragma pack(n) 的对齐规则:
1、偏移量要是,n和当前要存入变量大小中较小值的整数倍
2、整体大小要是n和最大变量大小中较小值的整数倍且n值必须为1,2,4,8…,为其他值时就按照默认的分配规则。
这和上面的对齐规则没有多大区别只不过在要存入变量时,要在变量所占字节和我们设置的字节(n)之间,取较小数,来和偏移量进行计算判断是否可以整除。
总结
内存对齐是由编译器、硬件、操作系统以及编程语言的特性共同实现的。编译器负责生成对齐的数据结构和代码,硬件提供对齐访问的性能优势,操作系统管理内存分配时考虑对齐要求,而编程语言提供控制对齐的工具和指令。这些共同作用确保程序在执行时具有高效的内存访问和最佳的性能。
原文地址:https://blog.csdn.net/2301_80774875/article/details/145241884
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!