c语言结构体内存对齐详解

c语言结构体内存对齐四大规则


规则一、

结构体成员的内部偏移量(内部地址)要被这个成员的数据类型大小整除!

简单来说,就是结构体的内存从零开始数,如果要放什么数据类型的变量对应的位置要能被该数据类型大小整除,如果不能,就往后找。

如果我定义了一个char和int类型的数据

struct student{
char a;
int b;
}

char是一个字节,整除起始0位置(每个数据类型在开始都能整除),int类型是四个字节所以存储时要找四的倍数,所以会空出三位,这个也要算到结构体内存中。所以如果我们用sizeof()来计算student的大小会得到8个字节的大小。规则一就介绍完了,可以用编译器多试试。

在这里插入图片描述

规则二、

整个结构体的大小,必须是最大成员的size的整数倍,否则需要在末尾补充空白字符

这个就很容易理解了,通过规则一,计算出的总大小,然后除以最大数据结构(占字节最大的数据类型)如果可以整除,那不用补,反之,要补。

如果我定义了一个char和int类型的数据

struct student{
int a;
char b;
}

这个如果按照规则一计算结构体内存应该为五个字节,但是编译器运行结果为8个字节。就是因为规则二,补了空白字符,使得内存大小可以被整除,规则二也讲完了。
在这里插入图片描述

规则三、

对于结构体中的结构体(结构体的嵌套),按照结构体展开后的内存对齐来处理

就是,按照你嵌套结构体的最大数据类型大小来对齐起始位置,后面的拆开融入到大结构体内

举个例子,就好像大塑料袋套小塑料袋,我们是将小塑料袋内最大数据类型大小按照规则一确定起始位置,
然后,把小塑料袋拆开,排列

struct A {
	int a;
	double b;
};
struct B {
	char c;
	struct A d;
};
int main()
{
	struct A num1;
	struct B num2 = { 1,{0,1} };
	printf("%d ", sizeof(num1));
	printf("%d ", sizeof(num2));
	unsigned char* p = (unsigned char*)&num2;
	for (int i = 0; i < sizeof(num2); i++)
	{
		printf("[%X]", *p);
		p++;
	}
}

在这里插入图片描述
由运行结果我们可以理解规则三的意思

画图理解一下

在这里插入图片描述

拆开B
在这里插入图片描述

至此,规则三就讲解完了。

规则四、

人为规定的特殊规则!!!

用#pragma pack(起始位置为什么的倍数)来规定

#pragma pack(2)
struct A {
	char a;
	int b;
	char c;
};
int main()
{
	struct A num1;
	printf("%d ", sizeof(num1));
}

在这里插入图片描述

这个规则替代了规则一,但是如果人为规则所得内存值比规则一大,则仍按规则一的内存。

总结:

以上规则都是为了规定内存,方便程序员管理,在写程序时,应该要考虑如何使内存足够小。在嵌入式开发和物联网工程中,第四条人为规则一般取1,即不存在空白区域,完全使用内存。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值