1.理论讲解
在嵌入式的学生中,我们常会遇见结构体这样一个我们熟悉的老朋友,结构体中可以存储不同类型的数据,在一定程度上节省内存空间,方便数据的管理,而在结构体中我们又有一种数据存储的方式结构体对齐,而结构体对齐有以下优点
结构体对齐的优点主要体现在以下几个方面:
-
提高内存访问效率:结构体对齐能够确保CPU在读取数据时,一次可以读取多个字节的数据,从而减少内存访问的次数和时间。例如,对于32位CPU,一次可以读取4个字节(即32位),如果结构体成员没有对齐,那么每次读取可能需要跨多个内存区间,导致额外的开销。
-
节省内存空间:通过优化对齐粒度,可以减少内存中的空洞浪费。例如,对齐粒度越小,浪费的内存空洞就越少,从而节省了宝贵的内存空间。
-
提升程序性能:对齐后的结构体成员可以更高效地被CPU读取,避免了因为对齐不当而导致的额外的内存访问开销。这不仅提高了程序的运行速度,还提升了整体的性能。
-
跨平台兼容性:在不同的硬件平台上,某些特定类型的数据只能从某些特定地址开始存取,如果不进行对齐,可能会导致硬件异常。因此,结构体对齐有助于保证代码的可移植性和跨平台兼容性。
-
减少内存读取时间:对齐满足成员最大字节数为基数的话可以增快内存的读取速度,但占空间大,以空间换时间。手动设置的对齐字节如果比成员最大字节要小,则能省下空间,但内存读取效率降低。
通过上面的讲解我们知道了结构体对齐的优点,那什么是结构体对齐,和为什么结构体对齐之后会有这么多的优点呢?
2.实际存储讲解
我们用下面这段代码来进行讲解,在下面这段代码中,我们定义了一个结构体在这个结构体中有三个变量 一个char型变量,一个int型变量,一个float型变量,如果以我们以往的知识这个结构在内存中所占的空间位9个字节(补充:int类型数据在内存中占4个字节 char类型数据在内存中占1个字节 float类型数据在内存中占4个字节)所以4+4+1=9
typedef struct
{
char a;
int b
float c;
};
其在内存中的位置可以理解位下图(我们假设每一行是四个字节的存储空间)我们知道结构的数据存储在内存中是连续的,所以就会有下面的存储方式
还是上面同样的代码,这个时候如果我们使用了结构体对齐,在使用了结构体对齐之后下面这段代码在内存中所占空间就是12个字节(4+4+4=12),这个时候大家就会有疑问了,为什么在我们使用结构体对齐之后内存空间的占有比没有使用结构体对齐之前多了三个字节的存储,这又是为什么呢?
typedef struct
{
char a;
int b
float c;
};
我们还是用画图来讲解这个问题,在使用了结构体对齐后,我们的存储方式与之前有了很大的不同,在之前的存储中,每一行可以存储四个字节,我们会尽量将每一行都存满,就比如第一行第一个字节我们存储了char型数据之后 我们还剩三个字节的空间,这个时候我们将部分int类型的数据存储在这三个字节中,然后再在下一行将剩余的一个字节的int类型的数据进行存储,而这样的存储方式在读写的时候就会占用时间,就比如我现在要读取int类型的这个数据我,我需要现在第一行进行读取然后又跳到第二行进行读取,为了节省时间和提高访问效率,我们使用了结构体对齐,我们确保每个数据都存储在一行之内,不让数据出现存储在不同行的问题 这样就可以使我们的数据读写更高效便捷。