一、前序:
1、系统之所以需要地址对齐,是因为系统采取了牺牲空间来换取效率。
2、进行地址对齐计算前需要清楚知道,当前使用的系统时多少位的系统。
3、必须清楚知道每一种基本类型,在占多少个字节。注:相同的基本类型在32位系统和在64位系统都有可能不同。如 short类型在32位系统占2个字节;在64位系统占4个字节。
二、计算:
1、在32位系统下,该结构体占用的字节数:12Byte
struct node{
char a; //1Byte, 存储地址:1 * N
int b; //4Byte, 存储地址:4 * N
short c; //2Byte, 存储地址:2 * N
}
1)N为正整数。说明每个类型需要存放在M * N的整数倍位置。所以该结构体占用12个字节。空间分布:0-3字节存储a;4-7字节存储b;8-11存储c。如果处理器需要取某个成员最少需要一个取值指令就能获取到对应的数据。
2) 如果不进行地址对齐,该结构体的成员都是紧挨着存放的,所以会占用7个字节。这样会导致系统的效率会大大减少。系统是32位,系统每次在存储器里取数据是可以取32位即4字节。系统取成员数据会进行,第一次取的数据包括成员a以及成员b的前3个字节,第二次再去b的最后一个字节、c的两个自己以及一个空字节。可以看出,如果处理器要获取成员b需要两次的取值指令才可以把b取出,这就会导致系统效率降低。
3)通过1)和2)对比就可以看出地址对齐,是系统实现用空间换时间的的设计。如果1)中成员没有占够4个字节,就会填充0来补齐。结构体的自然存储倍数取决于成员的最大自然倍数M(node) = max(1, 4, 2) = 4。
三、计算结构体嵌套的形式:
计算在32位系统下的struct node占多少个字节:
struct node1{
char a; //1byte, 存储地址: 1 * N
double b; //8byte, 存储地址: 8 * N
float c; //4byte, 存储地址: 4 * N
long long d; //8byte, 存储地址: 8 * N
}
struct node{
int e; //4byte, 存储地址: 4 * N
struct node1 f; //24byte, 存储地址: 8 * N M = MAX(1, 8, 8, 1)
double g; //8byte, 存储地址: 8 * N
char h; //1byte, 存储地址: 1 * N
}
sizeof(struct node1) = 32
sizeof(struct node) = 56