嵌套struct类定义中的sizeof
这里有个陷阱,对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子:
1 struct s1
2 {
3 char a[8];
4 };
5
6 struct s2
7 {
8 double d;
9 };
10
11 struct s3
12 {
13 s1 s;
14 char a;
15 };
16
17 struct s4 //s1为1对齐,大小为8
18 {
19
20 s1 s;
21 double d;
22 };
23
24 struct s5
25 {
26 s2 s;
27 char a;
28 };
29
30
31
32 cout << sizeof(s1) << endl; // 8
33 cout << sizeof(s2) << endl; // 8
34 cout << sizeof(s3) << endl; // 9
35 cout << sizeof(s4) << endl; // 16
36 cout << sizeof(s5) <<endl; //16
再考虑:
1 struct s1
2 {
3 char a[9];
4 };
5
6 struct s2
7 {
8 double d;
9 };
10
11 struct s3
12 {
13 s1 s;
14 char a;
15 };
16
17 struct s4 //s1为1对齐,大小为9
18 {
19
20 s1 s;
21 double d;
22 };
23
24 struct s5
25 {
26 s2 s;
27 char a;
28 };
29
30
31
32 cout << sizeof(s1) << endl; // 9
33 cout << sizeof(s2) << endl; // 8
34 cout << sizeof(s3) << endl; // 10
35 cout << sizeof(s4) << endl; // 24
36 cout << sizeof(s5) <<endl; //16
s1和s2大小虽然都是8,但是s1的对齐方式是1,s2是8(double),所以在s3和s4中才有这样的差异。
所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。
位域结构体中的对齐问题
在结构体和类中,可以使用位域来规定某个成员所能占用的空间,所以使用位域能在一定程度上节省结构体占用的空间。不过考虑下面的代码:
1 struct s1
2 {
3 int i: 8;
4 int j: 4;
5 double b;
6 int a:3;
7 };
8
9 struct s2
10 {
11 int i;
12 int j;
13 double b;
14 int a;
15 };
16
17 struct s3
18 {
19 int i;
20 int j;
21 int a;
22 double b;
23 };
24
25 struct s4
26 {
27 int i: 8;
28 int j: 4;
29 int a:3;
30 double b;
31 };
32
33 struct s4
34 {
35 double b;
36 int i: 8;
37 int j: 4;
38 int a:3;
39 };
40
41 cout<<sizeof(s1)<<endl; // 24
42 cout<<sizeof(s2)<<endl; // 24
43 cout<<sizeof(s3)<<endl; // 24
44 cout<<sizeof(s4)<<endl; // 16
45 cout<<sizeof(s5)<<endl; // 16
可以看到,有double存在会干涉到位域(sizeof的算法参考上一节),所以使用位域的的时候,最好把float类型和double类型放在程序的开始或者最后。不要让double干扰你的位域。
责任编辑:小草