结构体内存对齐_C语言

概念!

了解结构体对齐之前,先来了解几个概念!

对齐值说明
自身对齐值数据成员本身的对齐值,如:char类型占1个字节,即自身对齐值为1,short类型占2个字节,自身对齐值为2,int类型占4个字节,自身对齐值为4,double类型占8个字节,自身对齐值为8;
指定对齐值1、由编译器指定:32位机是个4字节,即指定对齐值为4,64位机是个8字节,即指定对齐值为8; 2、由程序员指定: 使用#pragma pack(n)来指定,n为2的幂次方,如1,2,4,8,16等;
有效对齐值自身对齐值指定对齐值中较小的那个 ,如:32位机,char类型,则此成员有效对齐值为1;double类型,则此成员有效对齐值为4;如:程序员指定#pragma pack(2)char类型,则此成员有效对齐值为1;double类型,则此成员有效对齐值为2;

这里值得一提的是指针、数组、结构体的自身对齐值以及有效对齐值;
指针: 指针存放的是地址,32位机的指针无论什么类型都是占用4个字节,其自身对齐值为4;64位机的指针则是8;
数组: 数组则是看其数据类型,如char[n]无论n为多少,其自身对其值都为1;int[n]无论n为多少,其自身对齐值都为4;
结构体: 结构体的自身对其值为其最大数据成员的自身对齐值,如最大数据成员为char,则结构体的自身对齐值为1;最大数据成员为double,则结构体的自身对齐值为8;

指针、数组、结构体的有效对齐值: 都为自身对齐值指定对齐值中较小的那个;

到此,我们开始讲解规则!!!

对齐规则!

规则1:存放成员的起始地址必须为此成员有效对齐值的整数倍。

举个例子,以32位机为例:

/*假如结构体初始地址为0x0000*/
struct name{
	char a;   //(1)
	short b;  //(2)
	int c;    //(3)
	double d; //(4)
	char *e;  //(5)
	char f[3];//(6)
};

(1) "char a"有效对齐值为1,此时地址为0X0000,是有效对齐值的0倍,则a存放在0x0000,占1个字节,所以下一个地址是0x0001;
(2) "short b"有效对齐值为2,此时地址为0X0001,不是有效对齐值的整数倍,无法存放b,则要从下个是有效对齐值整数倍的地址存放,0x0002便是有效对齐值的1倍,所以b存放在0x0002,占2个字节,下一个地址是0x0004;
(3) "int c"有效对齐值为4,此时地址为0x0004,是有效对齐值的1倍,则c存放在0x0004,占4个字节,下一个地址是0x0008;
(4) "double d"有效对齐值为4,此时地址为0x0008,是有效对齐值的2倍,则d存放在0x0008,占8个字节,下一个地址是0x0010;
(5) "char *e"有效对齐值为4,此时地址为0x0010,是有效对齐值的4倍,则e存放在0x0010,占4个字节,下一个地址是0x0014;
(6) "char f[3]"有效对齐值为1,此时地址为0x0014,是有效对齐值的20倍,则f存放在0x0014,占3个字节,下一个地址是0x0017;
结构体内存图

规则2:存放结构体的起始地址必须为此结构体有效对齐值的整数倍。

在了解这一规则前我们先来说说结构体在内存中占多少空间,像"char"占1个字节,"int"占4个字节等等;我们知道结构体在内存中是顺序存储的,像我们上面声明的结构体"struct name"在内存中占24个字节"0x0000-0x0017",为什么不是23个字节呢,其实这跟结构体的有效对齐值有关,结构体的大小是其有效对齐值的整数倍,这是考虑到结构体数组的原因;此时就很好理解上面的结构体为什么是占24个字节了,其有效对其值是4,如果23个字节显然不是4的整数倍,所以需要补足1个字节,也就是24个字节了。

了解好后我们来为规则2举个例子,以32位机,还有上面声明的结构体为例:

/*假如结构体初始地址为0x0000*/
struct{
	struct name a;//(1)
	short b;	  //(2)
	struct name c;//(3)
}A;

(1) "struct name a"有效对齐值为4,此时地址为0X0000,是有效对齐值的0倍,则a存放在0x0000,占24个字节,所以下一个地址是0x0018;
(2) "short b"有效对齐值为2,此时地址为0X0018,是有效对齐值的12倍,则b存放在0x0018,占2个字节,所以下一个地址是0x001A;
(3) "struct name c"有效对齐值为4,此时地址为0X001A,不是有效对齐值的整数倍,无法存放c,则要从下个是有效对齐值整数倍的地址存放,0x001C便是有效对齐值的7倍,所以c存放在0x001C,占24个字节,下一个地址是0x0034;
结构体内存图

讲到这里也就结束了,如文章有出错的地方请大佬们帮忙指点,谢谢!

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值