C++sizeof使用规则及陷阱分析四
来源:优易学  2011-11-9 14:23:52   【优易学:中国教育考试门户网】   资料下载   IT书店

  嵌套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干扰你的位域。

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训