关于对齐的内容事实上比较复杂,更详细的一篇文章参见: https://blog.csdn.net/Sansipi/article/details/121597464 面试的时候一般只会问结构体对齐的规则是什么?只要记住下面的内容就ok了
1. 无pragma pack的结构体对齐规则
- 分配内存的顺序是按照声明的顺序
- 结构体内每一个数据成员的起始位置(第一个元素的起始位置看成0)都应当能被该成员的大小整除,如果不能,就需要对该成员的前一个成员进行填充
- 对于整个结构体而言,还需要满足整个结构体的大小能被大小最大的成员的大小整除,如果不能,就在最后一个成员进行填充
上面的规则比较拗口,下面是实例:
struct S {
int i;
short j;
double k;
int l;
} S1;
2. 有pragma pack的结构体对齐规则
关于pack的详细解释: see: https://docs.microsoft.com/en-us/cpp/preprocessor/pack?view=msvc-170
加入了#pragma pack(n)之后规则变成了(这是在一个面经里面看到的,希望有人能指出最原始的出处):
- 结构体内每一个数据成员的起始位置要是n和当前成员大小中较小值的整数倍
- 结构体的整体大小要是n和最大变量大小中较小值的整数倍
- n值必须为1,2,4,8,16,为其他值时就按照默认的分配规则
下面是具体的实例
#include <stddef.h>
#include <stdio.h>
#pragma pack(push)
#pragma pack(2)
struct S {
int i;
short j;
double k;
int l;
} S1;
#pragma pack(pop)
int main() {
printf("%zu ", offsetof(S, i));
printf("%zu ", offsetof(S, j));
printf("%zu ", offsetof(S, k));
printf("%zu\n", offsetof(S, l));
printf("S1 size is : %ld\n", sizeof(S1));
}
程序输出结果: 这是32位平台下运行的结果。
下面是我觉得有用的参考资料: https://stackoverflow.com/questions/3318410/pragma-pack-effect
https://en.wikipedia.org/wiki/Data_structure_alignment
https://cloud.tencent.com/developer/article/1631792
|