深入剖析C++中的struct结构体字节对齐

2020-01-06 15:07:18于海丽

例3:空结构体


struct C{ 
  };
sizeof(C) = 0或sizeof(C);

C为空结构体,在C语言中占0字节,在C++中占1字节。

例4:结构体有静态成员


struct D{ 
   char a; 
   int b; 
   static double c; //静态成员 
};

静态成员变量存放在全局数据区内,在编译的时候已经分配好内存空间,所以对结构体的总内存大小不做任何贡献;因此,sizeof(D)=4+4=8个字节
例5:结构体中包含结构体


struct E{ 
  int a; 
  double b; 
  float c; 
}; 
struct F{ 
  char e[2]; 
  int f; 
  short h; 
  struct E i; 
};

在结构体E中最大对齐模数是sizeof(double)=8;且sizeof(E)=8+8+8=24个字节;在结构体F中,除了结构体成员E之外,其他的最大对齐模数是sizeof(int)=4;又因为结构体E中最大对齐模数是sizeof(double)=8;所以结构体F的最大对齐模数取E的最大对齐模数8;因此,sizeof(F)=4+4+8+24=40个字节。
例6:结构体包含共用体


union union1 
{ 
  long a; 
  double b; 
  char name[9]; 
  int c[2]; 
}; 
struct E{ 
  int a; 
  double b; 
  float c; 
  union1 MyUnion; 
};

共用体中的最大对齐模式是sizeof(double)=8;则sizeof(union1)=16;结构体E的最大对齐模数也是8;则sizeof(E)=8+8+8+16=40个字节。
例7:结构体包含指针成员


typedef struct A{ 
  char a; 
  int b; 
  float c; 
  double d; 
  int *p; 
  char *pc; 
  short e; 
}A;

结构体包含的指针成员的大小根据系统类型决定,由于这里是在win-32位系统下分析,则指针大小为4个字节;因此,结构体A的最大对齐模数为sizeof(double)=8;则sizeof(A)=4+4+8+8+4+4+8=40个字节。

存在#pragma pack宏的对齐


#pragma pack (n)  //编译器将按照n个字节对齐 
#pragma pack ()   //取消自定义字节对齐方式

对齐规则:
结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和自身对齐模数中较小的那个。
例8:按指定的对齐模数


#pragma pack (2) /*指定按2字节对齐*/ 
struct G{ 
  char b; 
  int a; 
  double d; 
  short c; 
}; 
#pragma pack () /*取消指定对齐,恢复缺省对齐*/

在结构体G中成员变量的最大对齐模数是sizeof(double)=8;又因为指定对齐模数是2;所以取其较小者2为结构体G的最大对齐模数;则sizeof(G)=2+4+8+2=16;由于16是2的整数倍,则不需要填充。