C 语言结构体对齐

自然对齐规则:

1.数据成员对齐规则

在默认情况下,各成员变量存放的起始地址相对于结构的起始地址的偏移量sizeof(基本类型)或其倍数。如果该成员为非基本成员,则为其子成员中最大的基本类型的整数倍。

2.整体对齐规则

结构的总大小也有个约束条件:最大sizeof(基本类型)的整数倍。

 

为什么对齐?

CPU在一个时钟周期内存取数据,效率高。

 

typedef struct {
    short s1;   // +0; size = 2 bytes
}s;

sizeof(s) = 2

 

 

 解释:

根据第一条规则起始位置是sizeof(s1)=2,0是2的倍数所以为sizeof(s) = 2。结构体总大小为子哦大sozeof(short)的整数倍。

 

typedef struct {
    int a;       // +0; size = 4 bytes
    double b;    // +8; size = 8 bytes
    short c;     // +16; size = 2 bytes
}s;

sizeof(s) = 24

 

 

 解释:

sizeof(a) = 4,所以占0,1,2,3字节。

sizeof(b) = 8,起始位置必须是8的倍数。所以4,5,6,7字节需要填充。

b从8号字节处开始存储。

sizeof(c) = 2, 16是2的倍数,所以从16号字节处开始存储。

现在所占空间字节数只有4 + 4(填充字节) + 8 + 2 = 18。不符合最后一条规则。

所以需要将剩下的6个字节填充。

所以最终所占的字节数为 4 + 4(填充字节) + 8 + 2  + 6(填充字节) = 24。

 

typedef struct {
    char a;       // +0; size = 1 byte
    short b;      // +2; size = 2 bytes
    char c;       // +4; size = 1 byte
    int d;        // +8; size = 4 bytes
}s;

sizeof(s) = 12

 

 

 解释:

sizeof(a) = 1,所以占起始的0号字节位。

sizeof(b) = 2,所以需要从2号字节开始占据。1号字节位则被填补。

sizeof(c) = 1,所以可以占据下一个字节也就是4号字节。

sizeof(d) = 4,所以起始地址必须为4的倍数,最近的四的倍数是8,所以前面的5,6,7被填补。

最后统计字节数为12,是最大类型int,sizeof(int) = 4的倍速。

所以最终所占的字节数为 :1 + 1(填充) + 2 + 1 + 3(填充) + 4  = 12。

 

typedef struct {
    char a;       // +0; size = 1 byte
    short b;      // +2; size = 2 bytes
    char c;       // +4; size = 1 byte
    int d;        // +8; size = 4 bytes
}s;

typedef struct {
    char c1;      // +0; size = 1 byte
    s s1;         // +4; size = 12 byte
    char c2;      // +16; size = 1 byte
}k;

sizeof(s) = 12

sizeof(k) = 20

解释:

sizeof(c1) = 1,所以占第一个字节。

s1中最大的类型的数据为int,所以s1的起始地址为4的倍数。1,2,3则被填充。

sizeof(s1) = 12,所以要占12个字节。

sizeof(c2) = 1,所以占16号字节。

结构的总大小也有个约束条件:最大sizeof(基本类型)的整数倍。

所以最终所占的字节数为 :1 + 3(填充) + 12 + 1 + 3(填充)  = 20。

posted @ 2020-09-07 18:10  Flag{Just_For_Fun}  阅读(244)  评论(0)    收藏  举报