天天看点

sizeof计算联合体大小问题

当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)。联合体有几个注意点:

1)联合体是一个结构;

2)它的所有成员相对于基地址的偏移量都为0;

3)此结构空间要大到足够容纳最"宽"的成员;

4)其对齐方式要适合其中所有的成员;

联合体的大小取决于它所有的成员中占有空间最大的一个成员的大小。并且对于复合数据类型,按照成员中最大成员的对齐方式对齐。

而struct结构体与类则需要计算所表示空间中所有成员的大小之和。

演示代码如:

  1. #include<iostream>  
  2. using namespace std;  
  3. union U1  
  4. {  
  5.     int n;  
  6.     char s[11];  
  7.     double d;  
  8. };  

联合体U1中,n占4字节,s[11]占11字节(因为一个char类型的数据占一个字节),d占8字节。那么联合体的大小取决于最大成员的大小即为11字节,但要考率最大字节的对齐方式,则在本例中最大字节为double类型的8字节,所以联合体要扩充成8字节的倍数,离11最接近的字节数,即为16字节。所以联合体的大小为16字节。

对齐是可以更改的,使用#pragma pack(x)可以改变编译器的对齐方式。C++固有类型的对齐取编译器对齐方式与自身大小中较小的一个。拿上面的代码为例:

  1. #include<iostream>  
  2. using namespace std;  
  3. #pragma pack(2)  
  4. union U1  
  5. {  
  6.     int n;  
  7.     char s[11];  
  8.     double d;  
  9. };  

由于使用手动更改对齐方式为2,所以double的对齐也变成了2(double本身的对齐为8),所以此时sizeof(u1)=12.

继续阅读