C/C++内存对齐策略

struct内存补齐属于笔试中的必考题目之一,但有时候stuct内存对齐的方式对让人感到非常疑惑,这里梳理一下内存对齐的策略。


策略

  • 规则一:前面的地址必须是后面地址的整数倍,不是就对齐;
  • 规则二:整个地址必须是最大字节的整数倍;
  • 规则三:指定#pragma pack(n),整个地址是n的整数倍。

实例

以32位环境为例(64位环境指针为8个字节,规则相同):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
struct s {
char *p; // 4字节
char c; // 4字节 规则一
int a; // 4字节
};
sizeof(s) = 12;
struct s {
char *p; // 4字节
char c; // 1字节
char ch[2]; // 3字节 规则一
int x; // 4字节
};
sizeof(s) = 12;
struct s {
char p; // 4字节 规则一
int x; // 4字节
char c; // 4字节 规则二
};
sizeof(s) = 12;
struct s {
char p; // 4字节 规则一
int x; // 4字节
char c; // 4字节
struct a {
char *b; // 4字节
long y; // 4字节
} inner; // 8字节
};
sizeof(s) = 20;
struct s {
char p;
char x;
struct a {
char b;
int y[10];
} inner;
char c;
};
sizeof(s) = 56;
struct s {
char p;
char x;
int f:1;
int b:2;
char c:1;
};
sizeof(s) = 12;
struct s {
char c; // 4字节 规则一
union u {
char *p;
short x;
} inner; // 四字节
};
sizeof(s) = 8;
union s {
char c;
struct u {
char p;
int x;
} inner;
};
sizeof(s) = 8;
#pragma pack(2)
struct s {
char *p; // 4字节
char x; // 2字节 规则三
int a; // 4字节
};
sizeof(s) = 10;
#pragma pack(1)
struct s {
char *p;
char x;
int a;
};
sizeof(s) = 9;
#pragma pack(8)
struct s {
char *p;
char x;
int a;
};
sizeof(s) = 16;