結(jié)構(gòu)體對齊
結(jié)構(gòu)體對齊的實際應(yīng)用
例 1:默認對齊 vs #pragma pack(2)
#include <stdio.h>
// 默認對齊(假設(shè)平臺:char=1, short=2, int=4)
struct S1
{
char c; // 地址0(對齊1)
short s; // 需對齊2 → 地址1不符合,填充1字節(jié)(地址1),s從地址2開始(占2-3)
int i; // 需對齊4 → 地址4開始(占4-7)
};
// 強制2字節(jié)對齊
#pragma pack(2)
struct S2
{
char c; // 地址0(對齊min(1,2)=1)
short s; // 對齊min(2,2)=2 → 地址1不符合,填充1字節(jié)(地址1),s從2開始(2-3)
int i; // 對齊min(4,2)=2 → 地址4是2的倍數(shù),直接存放(4-7)
};
#pragma pack()
int main()
{
printf("S1大小:%zu\n", sizeof(struct S1)); // 8字節(jié)(1+1+2+4=8,總對齊4)
printf("S2大小:%zu\n", sizeof(struct S2)); // 8字節(jié)(同上,因總對齊為2,8是2的倍數(shù))
return 0;
}
說明:此處S1和S2大小相同,但對齊邏輯不同(S1總對齊 4,S2總對齊 2)。
例 2:#pragma pack(1) 緊湊布局(無填充)
強制 1 字節(jié)對齊,徹底消除填充
#pragma pack(1)
struct S3
{
char c; // 地址0(對齊1)
int i; // 對齊min(4,1)=1 → 直接從地址1開始(1-4)
double d; // 對齊min(8,1)=1 → 從地址5開始(5-12)
};
#pragma pack()
// 大小計算:1(c) + 4(i) + 8(d) = 13字節(jié)(無任何填充)
printf("S3大小:%zu\n", sizeof(struct S3)); // 13字節(jié)
適用場景:需要精確控制內(nèi)存布局(如協(xié)議解析、硬件寄存器映射),但可能降低訪問性能。
例 3:attribute((packed))(GCC/Clang)
效果等同于#pragma pack(1)
struct S4
{
char c;
int i;
short s;
} __attribute__((packed)); // 緊湊對齊
// 大小:1 + 4 + 2 = 7字節(jié)(無填充)
printf("S4大小:%zu\n", sizeof(struct S4)); // 7字節(jié)
例 4:attribute((aligned(n))) 提高對齊要求
強制結(jié)構(gòu)體按更大的對齊值布局(常用于需要高效訪問的場景):
// 要求最小對齊16字節(jié)(即使成員最大對齊值小于16)
struct S5
{
int a; // 4字節(jié),默認對齊4
char b; // 1字節(jié),默認對齊1
} __attribute__((aligned(16)));
// 成員總大小:4 + 1 = 5字節(jié),需填充11字節(jié)滿足16對齊
printf("S5大小:%zu\n", sizeof(struct S5)); // 16字節(jié)

浙公網(wǎng)安備 33010602011771號