三步解决C语言中struct字节对齐问题

直入主题,要判断一个结构体所占的空间大小,大体来说分三步走:

1.先确定实际对齐单位,其由以下三个因素决定

    1> CPU周期

    WIN  vs  qt  默认8字节对齐

    Linux 32位 默认4字节对齐,64位默认8字节对齐

    2> 结构体最大成员(基本数据类型变量)

    3> 预编译指令#pragma pack(n)手动设置     n--只能填1 2 4 8 16

    上面三者取最小的,就是实际对齐单位(这里的“实际对齐单位”是我为了方便区分随便取的概念)

2.除结构体的第一个成员外,其他所有的成员的地址相对于结构体地址(即它首个成员的地址)的偏移量必须为实际对齐单位或自身大小的整数倍(取两者中小的那个)

3.结构体的整体大小必须为实际对齐单位的整数倍。

上面三步即是万能公式,下面看实际例子(linux 64系统下):

1.

上面nums中,没有手动设置对齐单位,linux64系统的默认对齐单位是8字节,结构体nums的最大成员double d占8个字节,故实际对齐字节是二者最小,即8字节。

char a放在结构体的起始地址;

short b占2个字节,2小于实际对齐字节8,故b的起始地址相对于a的起始地址的偏移量须为2的整数倍个字节;

int c占4个字节,4小于实际对齐字节8,故c 起始地址相对于a的起始地址的偏移量须为4的整数倍个字节;

double d占8个字节,8与实际对齐字节8相等,故d的起始地址相对于a的起始地址的偏移量须为8的整数倍个字节;

所以nums所占空间如下:    1(a)+1(浪费的空间,由b的起始地址决定这1字节必须腾出)+2(b)+4(c)+8(d)=16个字节

2.在上面结构体最后添加一个char数组,再看情况:

到成员double d为止,结构体nums占的空间是16,上面已经分析过,然后后面是一个char型数组,数组的类型是char[13],并不是基本数据类型,这里仍然当做13个char型变量来处理,char占1个字节,小于实际对齐字节8,所以这13个char型变量可以直接挨着double d后面放(最后结果看起来也就相当于整个数组挨着double d放置);所以总的空间情况是:1(a)+1(浪费空间)+2(b)+4(c)+8(d)+13(arr)=29;但29并不满足上面三步走的最后一步:“整个结构体的大小必须是实际对齐单位的整数倍”,所以29+5(浪费空间)=32,所以最后nums的空间情况是1(a)+1(浪费空间)+2(b)+4(c)+8(d)+13(arr)+5(浪费空间)=32字节

其实还有结构体中套结构体的情况,后面再补上~

猜你喜欢

转载自blog.csdn.net/m0_37829435/article/details/81348532