作者:牛客223996号
链接:https://www.nowcoder.com/exam/test/73333051/submission?examPageSource=Intelligent&pid=52556170&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21003&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网
类型长度
- 32位操作系统:
char : 1 int :4 short : 2 unsigned int : 4 long : 4
unsigned long : 4 long long : 8 float : 4 double : 8 指针: 4 - 64位操作系统
char : 1 int :4 short : 2 unsigned int : 4 long : 8
unsigned long : 8 long long : 8 float : 4 double : 8 指针: 8
结构体所占用的内存与其成员在结构体中的声明顺序有关,对齐规则:
-
每个成员分别按自己的对齐字节数(指它的类型而不是总长度,如double aa和char bb[9],应该是按照8对齐) 和 PPB(指定的对齐字节数,32位机默认为4,64位机为8)两个字节数最小的那个对齐。对齐 指成员它所在的存储位置是 两个字节数最小 的整数倍!!
-
复杂类型(如结构体)的默认对齐方式是它最长的成员的对齐方式。
-
结构体对齐后的长度必须是成员中最大的对齐参数~~(PPB)~~ 的整数倍。如32位系统中如果有double,最后总长度也是8的整数倍!
-
结构体作为数据成员的对齐规则:在一个struct中包含另一个struct,内部struct应该以它的最大数据成员大小(指它的类型而不是总长度)的整数倍开始存储。
-
结构体里面的如果成员为 指向结构体的指针,所占空间为当前系统下指针所占空间。
-
ps:只是成员之间的内存被浪费,并不是有成员多占用了内存。不够就补空字节。
举例1: 在64位操作系统中的大小。
struct t{ long a; short b; int c; int *d; char e; }
分析:
按照声明的顺序一个一个分配内存空间。首先 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。
举例2: 在32位操作系统中的大小。
struct t{ char a; int b; }; struct s{ char c; struct t d; char e; };
首先确定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.
举例3
union uti {
int n;
double g;
char ch[9];
} struct srt {
float xy;
union uti uv;
} aa;
union中最大字节对齐类型为double,8字节。所以struct中应以double为标准对齐,并且分配给union的空间应该>=9字节,综上,float需要一个8字节存储,union需要两个8字节存储,共需3*8=24字节。