结构体对齐

结构体对齐的实际应用

例 1:默认对齐 vs #pragma pack(2)

#include <stdio.h>

// 默认对齐(假设平台:char=1, short=2, int=4)
struct S1 
{
    char c;    // 地址0(对齐1)
    short s;   // 需对齐2 → 地址1不符合,填充1字节(地址1),s从地址2开始(占2-3)
    int i;     // 需对齐4 → 地址4开始(占4-7)
};

// 强制2字节对齐
#pragma pack(2)
struct S2 
{
    char c;    // 地址0(对齐min(1,2)=1)
    short s;   // 对齐min(2,2)=2 → 地址1不符合,填充1字节(地址1),s从2开始(2-3)
    int i;     // 对齐min(4,2)=2 → 地址4是2的倍数,直接存放(4-7)
};
#pragma pack()

int main() 
{
    printf("S1大小:%zu\n", sizeof(struct S1));  // 8字节(1+1+2+4=8,总对齐4)
    printf("S2大小:%zu\n", sizeof(struct S2));  // 8字节(同上,因总对齐为2,8是2的倍数)
    return 0;
}

说明:此处S1和S2大小相同,但对齐逻辑不同(S1总对齐 4,S2总对齐 2)。

例 2:#pragma pack(1) 紧凑布局(无填充)

强制 1 字节对齐,彻底消除填充

#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字节(无任何填充)
printf("S3大小:%zu\n", sizeof(struct S3));  // 13字节

适用场景:需要精确控制内存布局(如协议解析、硬件寄存器映射),但可能降低访问性能。

例 3:attribute((packed))(GCC/Clang)

效果等同于#pragma pack(1)

struct S4 
{
    char c;
    int i;
    short s;
} __attribute__((packed));  // 紧凑对齐

// 大小:1 + 4 + 2 = 7字节(无填充)
printf("S4大小:%zu\n", sizeof(struct S4));  // 7字节

例 4:attribute((aligned(n))) 提高对齐要求

强制结构体按更大的对齐值布局(常用于需要高效访问的场景):

// 要求最小对齐16字节(即使成员最大对齐值小于16)
struct S5 
{
    int a;  // 4字节,默认对齐4
    char b; // 1字节,默认对齐1
} __attribute__((aligned(16)));

// 成员总大小:4 + 1 = 5字节,需填充11字节满足16对齐
printf("S5大小:%zu\n", sizeof(struct S5));  // 16字节
posted @ 2025-11-05 00:10  开心猪扒  阅读(11)  评论(0)    收藏  举报