0x01 联合

联合允许以多种类型来引用一个对象

1
2
3
4
5
6
union U3{
char c;
int i[2];
double v;
}
//三种数据结构仅能存储一种

一个联合的总的大小等于它最大字段的大小

应用场景:

一个数据结构中的个不同字段的使用是互斥的,那么将这两个字段声明为联合的一部分 ,而不是结构的一部分,会减小分配空间的总量。

union还可以用来访问不同的数据类型的位模式,用一种数据类型才存储联合中的参数,又用另一种数据类型来访问它,除了有一样的位模式外,数值一般没有任何关联。

0x02 数据对齐

许多计算机系统对基本数据类型的合法地址做出了 些限制,要求某种类型对象的地址必须是某个值 K( 通常是2,4或8) 的倍数。这种对齐限制简化了形成处理器和内存系统之间接口的硬件设计。

对齐原则

对齐原则是任何K字节的基本对象的地址必须是K的倍数。

align 8

这段声明保证了它后面的数据的起始地址是8的倍数,常用于8字节数据类型的对齐。

结构体

看下面的例子:

结构体的起始地址和其中的数据类型,一般要满足对齐(对齐大小一般最大的数据类型大小)。

1
2
3
4
5
struct S1 { 
int i;
char c;
int j;
};

image-20240409180939599

如图所示,蓝色部分为了满足对齐而被浪费了。

结构体数组

结构的末尾有时候也需要填充,这样结构数组中的每个元素都会满足他们的对齐要求。

1
2
3
4
5
struct S2 { 
int i;
int j;
char c;
};

image-20240409181218102

只有在结构末尾填充,才能使得该结构体数组的每个结构的起始地址都是4的倍数。

0x03 结构体内偏移和填充的具体分布

研究复杂结构体内部的填充是怎么进行的,可以参考结构体数据类型的所占字节长度