首页 > 试题广场 >

sizeof(bu)的值是()

[单选题]
问题描述:
#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)的值是()
  • 20
  • 21
  • 22
  • 23
  • 24
  • 非以上选项
推荐
#pragma pack(2)
class BU
{
    int number; // 4
    union UBffer
    {
        char buffer[13]; // 13
        int number; // 4
    }ubuf; // union的大小取决于它所有的成员中,占用空间最大的一个成员的大小,并且需要内存对齐,这里因为#pragma pack(2),所以union的大小为14,如果不写#pragma pack(2),那么union大小为16【因为与sizeof(int)=4对齐】
    void foo(){} //0
    typedef char*(*f)(void*); //0
    enum{hdd,ssd,blueray}disk; // 4
}bu;

因此sizeof(union) = 4+14 +0 +0 +4 = 22
编辑于 2016-06-29 22:05:25 回复(25)
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

发表于 2016-06-03 13:42:44 回复(11)
枚举类型的sizeof值都是4;
enum只是定义了一个常量集合,里面没有“元素”,而枚举类型是当做int来存储的。
发表于 2016-08-29 00:21:25 回复(0)
答案错了,vs2012 x64下编译结果为22,选  E;
int =4
union=13+1=14
enum=4(内存中当成int来存储)
4+14+4=22
f只是一个定义,不是实际上的指针,没有占字节
但是如果我加入一个Int*,即:
class BU
{
int number;
union UBffer
{
char buffer[13];
int number;
}ubuf;
void foo(){}
typedef char*(*f)(void*);
enum{hdd,ssd,blueray}disk;
int *a;
}bu;
sizoef(bu)=30,int型指针占8个字节




发表于 2016-05-06 10:43:55 回复(9)
1.number,int类型,自身对齐是4,指定对齐是2,所以有效对齐是2,起始地址须是2的整数倍,放在[0-3];
2.ubuf,联合体,自身对齐是其成员自身对齐的最大值,数组看数组成员类型,所以这里的ubuf的自身对齐是4,指定对齐是2,所以有效对齐是2,这就决定了ubuf的起始地址须是2的整数倍,而且ubuf的总大小须是2的整数倍,所以放在[4,17],  (联合体的大小是其成员大小的最大值)
3.disk,枚举类型,自身对齐是4,指定对齐是2,所以有效对齐是2,这就要求disk的起始地址须是2的整数倍,而且disk的总大小须是2的整数倍,所以放在[18,21]。(枚举类型的大小是4字节)
最后,bu的自身对齐是4,指定对齐是2,所有有效对齐是2,这就要求bu的大小须是2的整数倍,所以是
22. (抛砖引玉,如有错误,欢迎指正!)
发表于 2016-08-03 11:37:19 回复(0)
typedef char*(*f)(void*); 这个是定义类型,不占用空间。
发表于 2016-06-23 12:19:39 回复(0)
联合体的内存除了取最大成员内存外,还要保证是所有成员类型size的最小公倍数。此处内存取13,但必须是int类型的倍数,所以应该是16,但是预编译中指出只需是2的倍数即可,所以次数取14
编辑于 2018-07-31 12:42:56 回复(0)
声援1楼。 一个Class对象占用内存空间:非静态成员变量总和+ 数据对齐处理+虚函数
编辑于 2016-05-07 17:07:55 回复(1)
枚举类型占4字节
发表于 2017-07-02 22:20:18 回复(0)
#pragma pack(2)
classBU
{
intnumber; //2字节
unionUBffer
{
charbuffer[13]; //13+1字节,对其原则
intnumber; //2字节
}ubuf;
voidfoo(){} //0字节
typedefchar*(*f)(void*); //0字节
enum{hdd,ssd,blueray}disk; //4字节
}bu;

注意一点,C++中类和结构体并无本质区别,类也需要满足对齐原则

类对象的大小=各非静态数据成员(包括父类的非静态数据成员但都不包括所有的成员数)的总和+ vfptr指针(多继承下可能不止一个)+vbptr指针(多继承下可能不止一个)+编译器额外增加的字节。

#pragma pack(n)

解释一:

每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。

规则:

1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。

2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
struct的空间计算较为复杂,总体上遵循两个原则:
1、整体空间是占用空间最大的成员(的类型)所占字节的整数倍,但在32位Linux+gcc环境下,若最大成员类型所占字节超过4,如double是8,则整体空间是4的倍数即可。
2、数据对齐原则——内存按结构体成员的先后顺序排列,当排到该成员时,其前面已摆放的空间大小必须是该成员类型大小的整数倍,如果不够则补齐,依次向后类推, 但Linux+gcc环境下,若最大成员 类型所占字节超过4,如double是8,则前面已摆空间是4的倍数即可。

编辑于 2016-09-02 23:58:03 回复(0)
首先了解union 的特点,在任意时刻只有一个数据成员可以有值,可以利用联合体;不能含有引用类型的成员; 含有构造函数或者析构函数的类类型也可以作为union的成员类型;默认union的成员都是公有的;union不能含有虚函数,不可继承,也不可被继承;默认的union是没有初始化的;定义一个未命名的union 我们可以直接访问它的成员(注意:匿名union不能包含保护成员或者私有成员,也不能定义成员函数)。
以下特点:
他是一个结构, 它的所有成员相对基地址的偏移量都为0; 此结构空间要大到足够容纳最“宽”的成员。
其对齐方式要适合其中所有的成员。
综上:分配给union的实际大小不仅要满足对齐大小的整数倍,而且要满足实际大小不能小于最大成员的大小。
若第一行没有#pragrama pack(2),则union占用字节是16,由于里面的成员最大的字节是13且又要保持int字节对齐,因而 13+3=16。
否则,union占用字节是 14。在类、结构或者union补齐字节的时候,找他们的成员数据中找字节最大的那个数与 pack(n)相比较,取两者中最小的。如题可知,补齐字节取的是2,因而是13+1=14.。为2的整数倍。
注意:枚举类型声明不占用内存,枚举类型的变量占用的字节数同整数int 。因而枚举类型均占4字节。

发表于 2017-02-08 16:03:30 回复(0)
函数指针为啥是0?
发表于 2016-09-11 13:54:35 回复(0)

类型的大小和对象的大小还是不一样的

发表于 2019-03-09 17:31:47 回复(0)
pack(n)
1、偏移量为当前值与n中较小值的整数倍
2、总大小为所有变量中最大值与n中较小值的整数倍
非虚函数与取别名不占内存
另外注意,如果类中存在虚函数,则每个类的对象都存在一个指向虚表的指针,要计算在总大小内
发表于 2018-09-10 23:00:46 回复(0)
枚举类型是个整型,占四个字节
发表于 2018-08-28 23:10:22 回复(0)
内存对齐,是指存储的尺寸,即sizeof结果要是对齐系数的整数倍。
发表于 2018-07-21 11:47:10 回复(0)
为什么函数指针不占内存,不是应该占4个吗?
发表于 2018-06-04 15:12:31 回复(0)
枚举类型,4字节
发表于 2017-12-04 19:30:02 回复(0)
枚举类型咋只占四个字节
发表于 2017-11-15 15:47:25 回复(0)
有个pack(2)
发表于 2017-09-24 12:38:42 回复(0)