- 问题描述
#pragma pack(2)
class BU
{
int number;
union UBffer
{
char buffer[13];
int number;
}ubuf;
void foo(){}
typedef char*(*f)(void*);
enum{hdd,ssd,blueray}disk;
}bu;
sizeof(bu)的值是()
A.20
B.21
C.22
D.23
E.24
F.非上述选项
-
分析
用sizeof计算类大小的一般原则- 成员函数(包括静态与非静态)和静态数据成员都不占用类对象的存储空间。
- 虚函数由于要维护虚函数表,所以要占据一个指针大小,也就是4字节
- 如果是子类,那么父类中的成员也会被计算
- 内存字节要对齐
- 空类的实例占用1字节
union:当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union); 它有以下特点:
- (1)它是一个结构;
- (2)它的所有成员相对于基地址的偏移量都为0;
- (3)此结构空间要大到足够容纳最"宽"的成员;
- (4)其对齐方式要适合其中所有的成员
而分配给union的实际大小不仅要满足是对齐大小的整数倍,同时要满足实际大小不能小于最大成员的大小。
本题目中
注意第一行,#pragma pack(2)
首先考虑没有这句话时,我们在类、结构或者union补齐字节的时候,
找它们的成员数据中找字节最大的那个数去衡量如何对齐,假设为z;
但是有了这句话以后,对齐方式是取 pack(n)中n和z的最小值去对齐;
可见本题中对齐字节数为2;
之后往下看 int number; 占4个字节
接下来考虑union大小
union UBffer { char buffer[13]; // 13 int number; // 4 }ubuf; buffer 是13个字节,number 是4个字节,取最大的 为13,注意还要字节对齐,对齐字节数为2,所以Union大小为14,既满足buffer的对齐 也满足number的对齐。 void foo(){} 不占 typedef char*(*f)(void*); 不占 enum{hdd,ssd,blueray}disk; 4个字节
综上,总大小为14+4+0+0 +4=22
另外:在64位机器中,指针占8个字节。32位机器,指针占4字节。