有一个如下的结构体:
1
2
3
4
5
6
|
struct A{ long a1; short a2; int a3; int *a4; }; |
请问在64位编译器下用sizeof(struct A)计算出的大小是多少?
- 24
- 28
- 16
- 18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
8 + 2 + 4 + 8 = 22, 对齐为24 32位编译器:32位系统下指针占用4字节 char :1个字节 char *(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器) short int : 2个字节 int : 4个字节 unsigned int : 4个字节 float : 4个字节 double : 8个字节 long : 4个字节 long long : 8个字节 unsigned long : 4个字节 64位编译器:64位系统下指针占用8字节 char :1个字节 char *(即指针变量): 8个字节 short int : 2个字节 int : 4个字节 unsigned int : 4个字节 float : 4个字节 double : 8个字节 long : 8个字节 long long : 8个字节 unsigned long : 8个字节 |
-
预备知识:基本类型占用字节在32位操作系统和64位操作系统上,基本数据类型分别占多少字节呢?32位操作系统:char : 1 int :4 short : 2 unsigned int : 4 long : 4 unsigned long : 4 long long : 8 float : 4 double : 8 指针 : 464位操作系统char : 1 int :4 short : 2 unsigned int : 4 long : 8 unsigned long : 8 long long : 8 float : 4 double : 8 指针 : 8内存对齐:成员对齐有一个重要的条件,即每个成员按自己的方式对齐。其对齐的规则是:每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里默认是8字节)中较小的一个对齐。并且结构的长度必须为所用过的所有对齐参数的整数倍。不够就补空字节。举例:复制代码struct t{long a;short b;int c;int *d;char e;}复制代码在64位操作系统中的大小。分析:按照声明的顺序一个一个分配内存空间。首先 long 型变量a,在64位地址空间中,long型占8个字节,所以按照上面的对齐条件,这个成员应该按照对其参数 min(sizeof(long), 8) = 8字节来对齐,所以把这个成员存放在 0~7 内存单元中。然后 short型变量b,在64位地址空间中,short型占2个字节,所以按照上面的对齐条件,这个成员应该按照对其参数 min(sizeof(short), 8) = 2字节来对齐,所以把这个成员存放在 8~9 内存单元中。然后 int型变量c,在64位地址空间中,int型占4个字节,所以按照上面的对齐条件,这个成员应该按照对其参数 min(sizeof(int), 8) = 4字节来对齐,所以把这个成员存放在 12~15 内存单元中(10,11单元都不能被4整除)。然后 int*型变量d,在64位地址空间中,指针型占8个字节,所以按照上面的对齐条件,这个成员应该按照对其参数 min(sizeof(int*), 8) = 8字节来对齐,所以把这个成员存放在 16~23 内存单元中。然后 char型变量e,在64位地址空间中,char型占1个字节,所以按照上面的对齐条件,这个成员应该按照对其参数 min(sizeof(char), 8) = 1字节来对齐,所以把这个成员存放在 24 内存单元中。然后整个结构体的长度必须为所有对齐参数的整数倍,当前长度为25,不是所有对齐参数整数倍,必须调整为32,才是所有参数整数倍。所以这个结构体的长度为32。如果结构体中出现子结构体怎么办?我们在确定子结构体的对齐参数时,应该就是它的所有成员使用的对齐参数中最大的一个。举例:复制代码struct t{char a;int b;};struct s{char c;struct t d;char e;};复制代码在32位操作系统下的长度。首先确定t的大小为8,它的所有成员使用的对齐参数最大为4。再考察s:首先 char 型变量c,在32位地址空间中,char型占1个字节,所以按照上面的对齐条件,这个成员应该按照对其参数 min(sizeof(char), 8) = 1字节来对齐,所以把这个成员存放在 0 内存单元中。然后 struct t型变量d,在32位地址空间中,struct t占8个字节,所以按照上面的对齐条件,这个成员应该按照对其参数 4 字节来对齐,所以把这个成员存放在 4~11 内存单元中。然后 char型变量e,在32位地址空间中,char型占1个字节,所以按照上面的对齐条件,这个成员应该按照对其参数 min(sizeof(char), 8) = 1字节来对齐,所以把这个成员存放在 12 内存单元中。然后整个结构体的长度必须为所有对齐参数的整数倍,当前长度为13,不是所有对齐参数整数倍,必须调整为16,才是所有参数整数倍。所以此结构体大小为16.