结构体内存对齐原因及机制详解

文章介绍了C语言中结构体的内存对齐机制,解释了为何结构体大小不简单等于各成员大小之和。通过一个structstudent的例子,说明了内存对齐的规则和目的——优化内存访问速度,减少CPU的额外操作,提高程序执行效率。
摘要由CSDN通过智能技术生成

        在C语言中,每种数据类型都有其固定的大小。比如,int类型系统为其分配4个字节的内存空间,char类型系统为其分配1个字节的内存空间。

        而结构体相对特殊,因为结构体包含多种不同类型的数据,每个数据的大小不一定相等。那么,结构体的大小是简单的由所包含的数据大小直接相加吗?

#define _CRT_SECURE_NO_WARNINGS 1
# include <stdio.h>

struct student
{
	int age;
	char name[10];
}s1;
int main()
{
	printf("%d", sizeof(s1));
}

 如果是直接相加的话,输出就是14。那么究竟是不是14呢?

为什么是16呢?

下面就来详细介绍一下结构体的内存对齐机制了。

在C语言中,为了优化内存访问速度,引入了内存对齐机制。其工作机制是,每个结构体成员根据‘默认对齐数'和'自身大小'取较小值作为其对齐数后,将对齐数的整数倍作为该成员所在内存地址,最后整个结构体的大小必须为’各成员的对齐数中的最大值‘的整数倍。

以上述结构体为例,vs2019的默认对齐数是8,成员age的大小是4个字节,因此成员age的对齐数是4,由于其位于开头(偏移量为0的内存地址,0是任何数的0倍),所以直接放在偏移量为0的内存地址中;成员name是char类型数组,以类型为准,char类型数据自身大小是1个字节,因此name的对齐数是1,存放在偏移量为4的内存地址中;目前,整个结构体的大小为14,由于最后整个结构体的大小必须为’各成员的对齐数(4和1)中的最大值(4)‘的整数倍,而14不是4的整数倍,因此要填充2个字节,最后整个结构体的大小为16。

        上面提到,内存对齐是为了优化内存访问速度,那么其优化的原理又是什么呢?因为它可以减少CPU对内存的读写次数,从而提高程序的执行效率。当CPU读取内存中的数据时,需要根据内存地址读取数据,如果读取的内存地址不是按照对齐规则对齐的,CPU需要进行额外的操作才能读取到数据。这个额外的操作可能包括多次访问内存、数据移位、数据合并等,这些操作都会增加CPU的负担,从而降低程序的执行效率。通过内存对齐,可以让避免了CPU进行额外的读写操作。例如,如果结构体中有两个变量,一个是4字节的int类型、一个是8个字节的double类型,若不存在内存对齐机制的话,CPU一次读取8个字节,这8个字节中,有4个字节是能组成一个完整的int类型成员的,但是另外4个字节并不是完整的,需要CPU进行下一轮读取并对其中的前4个字节进行移位和合并,才能恢复double类型的数据,降低了运行的效率;引入内存对齐机制后,int类型的数据和double类型的数据之间会被填充4个字节,CPU第一次读取8个字节,其中前4个是完整的int类型数据,第二次读取8个字节,这8个字节就是完整的double类型数据,减少了移位、合并等额外的操作,优化了读取效率,这样可以提高程序的执行效率,尤其是在处理大量数据的情况下,优化内存访问速度的效果更为显著。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值