当前所在位置:珠峰网资料 >> 计算机 >> 计算机等级考试 >> 正文
字节对齐问题
发布时间:2010/8/23 10:34:05 来源:城市学习网 编辑:ziteng
  规则:
  1 、数据成员对齐规则:结构 (struct)( 或联合 (union)) 的数据成员,第一个数据成员放在 offset 为 0 的地方,以后每个数据成员的对齐按照 #pragma pack 指定的数值和这个数据成员自身长度中,比较小的那个进行。
  2 、结构 ( 或联合 ) 的整体对齐规则:在数据成员完成各自对齐之后,结构 ( 或联合 ) 本身也要进行对齐,对齐将按照 #pragma pack 指定的数值和结构 ( 或联合 ) 最大数据成员长度中,比较小的那个进行。
  3 、结合 1 、 2 可推断:当 #pragma pack 的 n 值等于或超过所有数据成员长度的时候,这个 n 值的大小将不产生任何效果。 使用指令#pragma pack (n),编译器将按照 n个字节对齐。使用指令#pragma pack (),编译器将取消自定义字节对齐方式。在#pragma pack (n)和#pragma pack ()之间的代码按 n个字节对齐。
  struct s1
  {
  int a;
  char b;
  short e;
  int c;
  };
  struct s2
  {
  int a;
  char b;
  int c;
  short e;
  int d;
  };
  1字节对齐 为 11 和 15
  2字节对齐 为 11 和 16
  4字节对齐 为 12 和 20
  8字节对齐 为 12 和 20
  16字节对齐 为 12 和 20[NextPage]   看如下例子:
  #pragma pack(8)
  struct TestStruct4
  {
  char a;
  long b;
  };
  struct TestStruct5
  {
  char c;
  TestStruct4 d;
  long long e;
  };
  #pragma pack()
  问题:
  A) sizeof(TestStruct5)=?
  B) TestStruct5的 c 后面空了几个字节接着是 d ?
  TestStruct4中,成员 a 是 1字节,默认按 1字节对齐,指定对齐参数为 8,这两个值中取 1,a 按 1字节对齐;成员 b 是 4个字节,默认是按 4字节对齐,这时就按 4字节对齐,所以sizeof(TestStruct4)应该为 8。
  TestStruct5 中,c 和 TestStruct4 中的 a 一样,按 1字节对齐,而 d 是个结构,它是 8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个, TestStruct4的就是 4。所以,成员 d 就是按 4字节对齐。成员 e 是 8个字节,它是默认按 8字节对齐,和指定的一样,以它对到 8字节的边界上。这时,已经使用了12个字节了,所以又添加了 4个字节的空,从第 16个字节开始放置成员 e。这时,长度为24,已经可以被 8(成员 e 按 8字节对齐)整除。这样,一共使用了 24个字节。内存布局如下(*表示空闲内存,1表示使用内存,单位为 1byete) :
  a    b
  TestStruct4的内存布局:1***, 1111
  c     TestStruct4.a   TestStruct4.b                    d
  TestStruct5的内存布局: 1***,       1***,           1111,        ****,       11111111
  这里有三点很重要:
  首先,每个成员分别按自己的方式对齐,并能最小化长度。
  其次,复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。
  然后,对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐。
  补充一下:
  对于数组,比如:char a[3],它的对齐方式和分别写 3个 char 是一样的,也就是说它还是按 1 个字节对齐。如果写:typedef char Array3[3];Array3 这种类型的对齐方式还是按 1 个字节对齐,而不是按它的长度。
广告合作:400-664-0084 全国热线:400-664-0084
Copyright 2010 - 2017 www.my8848.com 珠峰网 粤ICP备15066211号
珠峰网 版权所有 All Rights Reserved