结构体字节对齐

结构体的各个成员并不是一个紧挨着一个的,中间可能有填充(Padding),不仅如此,在结构体的结尾可能也有填充。

结构体字节对齐_第1张图片

结构体字节对齐_第2张图片

最后sizeof(s)的值为12, 并不是1+2+4+1=8,出现这种现象的原因是计算机体系结构对于访问内存的限制,访问4字节的指令所访问的内存地址应该是4的整数倍,访问2字节的指令所访问的内存地址应该是2字节的整数倍,这称为对齐(Alignment)。

对于上面的结构体,编译器会把它的基地址对齐到4字节边界,也就是说, ebp-0x10这个地址一定是4的整数倍。s.a占一个字节,没有对齐问题,s.b占两个字节,如果s.b紧挨在s.a后面,它的地址就不能是两个字节的整数倍,所以编译器插入一个字节填充。 s.c占4个字节,紧挨在s.b后面就可以了,因为ebp-0xc这个地址也是4的整数倍。最后面尾端填充字节的想法是,如果构造一个结构体数组,如果整体不是4字节对齐的,后面第二个元素的起始地址将不是4字节整数倍。

判断:
1、在结构体中的不同数据类型,根据后面一个数据类型的大小决定前一个数据大小应该是几字节的整数倍
2、最后整体应该是其中大小最大元素size(与系统的位数有关系)的整数倍

下面是具体的两个例子:
结构体字节对齐_第3张图片
char和int间填充2个字节,总共字节大小为12字节(4字节的整数倍)

结构体字节对齐_第4张图片
总共字节大小为24个字节,char和long之间填充6个字节,尾端填充4个字节,最终是8字节的整数倍

上面所述的都是系统默认的情况,可以使用预编译指令#progma pack (value)来告诉编译器,使用我们指定的对齐值来取代缺省的。如果希望不设置字节对齐,使用# progma pack(1),即使用一个字节的对齐。

你可能感兴趣的:(C++/C)