面试题答案
一键面试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
字节。
- 每个成员按1字节对齐。
#pragma pack(2)
:char a
按1字节对齐,int b
按2字节对齐(因为2
和4
中较小值为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字节。
- 同