MST

星途 面试题库

面试题:C语言#pragma pack指令深度解析

在C语言中,#pragma pack(n)指令用于指定结构体、联合等类型数据的对齐方式。请解释该指令的工作原理,包括不同n值对结构体成员对齐和结构体整体大小的影响。同时,给出一个示例结构体,分别展示在不同#pragma pack(n)设置下,结构体的内存布局变化。
21.6万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

1. #pragma pack(n)工作原理

#pragma pack(n)指令用于指定结构体、联合等类型数据的对齐方式。这里的n表示按照n字节对齐。

结构体成员对齐

编译器在为结构体成员分配内存时,会按照#pragma pack(n)指定的对齐值n和结构体成员自身大小中较小的那个值来进行对齐。例如,如果n = 4,而某个成员是char类型(1字节),则该成员按照1字节对齐;如果某个成员是int类型(4字节),则按照4字节对齐。

结构体整体大小

结构体整体大小不仅要保证每个成员都按照指定规则对齐,而且结构体的大小必须是其最大对齐成员大小(按照#pragma pack(n)调整后)的整数倍。如果不满足,编译器会在结构体末尾填充字节以满足这一条件。

2. 示例结构体及不同#pragma pack(n)设置下的内存布局变化

#include <stdio.h>

// 示例结构体
struct Test {
    char a;
    int b;
    short c;
};

// 测试不同的#pragma pack(n)设置
int main() {
    // #pragma pack(1)
    #pragma pack(1)
    struct Test1 {
        char a;
        int b;
        short c;
    };
    printf("When #pragma pack(1), sizeof(Test1) = %zu\n", sizeof(struct Test1));

    // #pragma pack(2)
    #pragma pack(2)
    struct Test2 {
        char a;
        int b;
        short c;
    };
    printf("When #pragma pack(2), sizeof(Test2) = %zu\n", sizeof(struct Test2));

    // #pragma pack(4)
    #pragma pack(4)
    struct Test3 {
        char a;
        int b;
        short c;
    };
    printf("When #pragma pack(4), sizeof(Test3) = %zu\n", sizeof(struct Test3));

    // #pragma pack(8)
    #pragma pack(8)
    struct Test4 {
        char a;
        int b;
        short c;
    };
    printf("When #pragma pack(8), sizeof(Test4) = %zu\n", sizeof(struct Test4));

    // 恢复默认对齐
    #pragma pack()

    return 0;
}

结果分析

  • #pragma pack(1)
    • 每个成员按1字节对齐。char a占1字节,int b占4字节,short c占2字节。结构体总大小为1 + 4 + 2 = 7字节。
  • #pragma pack(2)
    • char a按1字节对齐,int b按2字节对齐(因为24中较小值为2),short c按2字节对齐。a占1字节,然后填充1字节达到2字节对齐,b占4字节,c占2字节。结构体总大小为(1 + 1) + 4 + 2 = 8字节。
  • #pragma pack(4)
    • char a按1字节对齐,填充3字节达到4字节对齐,int b按4字节对齐,short c按2字节对齐,填充2字节达到4字节对齐。结构体总大小为(1 + 3) + 4 + (2 + 2)= 12字节。
  • #pragma pack(8)
    • #pragma pack(4),因为最大对齐成员int的大小4小于8,所以布局和#pragma pack(4)一样,结构体总大小为12字节。