结构体内存对齐

对齐原则

(1) 数据成员对齐:结构struct(或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#paragma pack指定的数值和这个数据成员自身长度比较小的进行
(2) 结构(或联合)的整体对齐:#paragma pack指定的数值和结构(或联合)最大数据成员长度较小的进行
(3) 结构体内部的结构体成员要从内部最大元素大小的整数倍地址开始存储

例一:一字节对齐
第一步:成员数据对齐
#pragma pack(1)
struct AA
{
	int a;   //长度4 < 1 按1对齐;偏移量为0;存放位置区间[0,3]
	char b;  //长度1 = 1 按1对齐;偏移量为4;存放位置区间[4]
	short c; //长度2 > 1 按1对齐;偏移量为5;存放位置区间[5,6]
	char d;  //长度1 = 1 按1对齐;偏移量为7;存放位置区间[7]
    //整体存放在[0~7]位置区间,共8个字节
};
#pragma pack()
第二步:整体对齐

整体对齐系数 = min((max(int,short,char), 1) = 1,不需要再进行整体对齐

例二:二字节对齐
第一步:成员数据对齐
#pragma pack(2)
struct AA
{
	int a;   //长度4 < 1 按2对齐;偏移量为0;存放位置区间[0,3]
	char b;  //长度1 < 2 按1对齐;偏移量为4;存放位置区间[4]
	short c; //长度2 = 2 按2对齐;偏移量提升到2的倍数6;存放位置区间[6,7]
	char d;  //长度1 < 2 按1对齐;偏移量为8;存放位置区间[8]
};
#pragma pack()
第二步:整体对齐

整体对齐系数 = min((max(int,short,char), 2) = 2,将9提升到2的倍数,10个字节

例三:四字节对齐
第一步:成员数据对齐
#pragma pack(4)
struct AA
{
	int a;   //长度4 = 4 按4对齐;偏移量为0;存放位置区间[0,3]
	char b;  //长度1 < 4 按1对齐;偏移量为4;存放位置区间[4]
	short c; //长度2 < 4 按2对齐;偏移量提升到2的倍数6;存放位置区间[6,7]
	char d;  //长度1 < 4 按1对齐;偏移量为8;存放位置区间[8]
};
#pragma pack()
第二步:整体对齐

整体对齐系数 = min((max(int,short,char), 4) = 4,将9提升到2的倍数,12个字节

例三:八字节对齐
第一步:成员数据对齐
#pragma pack(8)
struct AA
{
	int a;   //长度4 < 8 按4对齐;偏移量为0;存放位置区间[0,3]
	char b;  //长度1 < 8 按1对齐;偏移量为4;存放位置区间[4]
	short c; //长度2 < 8 按2对齐;偏移量提升到2的倍数6;存放位置区间[6,7]
	char d;  //长度1 < 8 按1对齐;偏移量为8;存放位置区间[8]
};//9字节
#pragma pack()
第二步:整体对齐

整体对齐系数 = min((max(int,short,char), 8) = 4,将9提升到4的倍数,12字节

例四:结构体包含结构体的运算
struct AA
{
	int a;	//长度4 < 8 按4对齐;偏移量为0;存放位置区间[0,3]
	char b; //长度1 < 8 按1对齐;偏移量为4;存放位置区间[4]
	short c;//长度2 < 8 按2对齐;偏移量提升到2的倍数6;存放位置区间[6,7]
    //结构体内部最大元素为int,由于偏移量为8刚好是4的整数倍,所以从8开始存放接下来的struct FF
	struct FF
	{
		int a1;//长度4 < 8 按4对齐;偏移量为0;存放位置区间[8,11]
		char b1;//长度1 < 8 按1对齐;偏移量为12;存放位置区间[12]
		short c1;//长度2 < 8 按2对齐;偏移量提升到2的倍数14;存放位置区间[14,15]
		char d1;//长度1 < 8 按1对齐;偏移量为16;存放位置区间[16]
	};
    //整体对齐系数=min(max(int,short,char),8)=4,将偏移量提升到4的倍数20
	char d;//长度1 < 8 按1对齐;偏移量为21;存放位置区间[21]
};
//整体对齐系数,min((max(int,short,char), 8)=4;偏移量提升到4的倍数24

例五:嵌套结构体
struct B
{
    char e[2];//长度2 < 8 按2对齐;偏移量为0;存放位置区间[0,1]
    short h;  //长度2 < 8 按2对齐;偏移量为2;存放位置区间[2,3]
    //结构体A内部double字节长度最长,8字节
    struct A
    {
        int a;//长度4 < 8 按4对齐;偏移量提升8的倍数8;存放位置区间[8,11]
        double b;//长度8 == 8 按8对齐;偏移量提升到8的倍数16;存放位置区间[16,23]
        float c;//长度4 < 8 按4对齐;偏移量为24;存放位置区间[24,27]
    }
}//28字节
//整体对齐=min(max(char e[2], short, int double, float), 8)=8
//对齐到8的整数,32字节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值