面试题答案
一键面试- 计算大小:
sizeof(InnerS)
:short
通常为2字节,char
为1字节。在C++ 中,结构体存在内存对齐,假设默认对齐规则(一般是按照最大成员的对齐方式对齐),short
最大,其对齐方式为2字节对齐。InnerS
的成员s1
占用2字节,c1
占用1字节,为了满足2字节对齐,c1
后面会填充1字节。所以sizeof(InnerS)=4
字节。sizeof(InnerU)
:- 联合体的大小是其最大成员的大小。
long
通常为4字节(在32位系统)或8字节(在64位系统),假设这里long
为4字节,InnerS
为4字节。所以sizeof(InnerU)=4
字节。
- 联合体的大小是其最大成员的大小。
sizeof(OuterS)
:InnerU
为4字节,double
为8字节,InnerS
为4字节。按照内存对齐规则,结构体OuterS
以double
的8字节对齐方式对齐。InnerU
占用4字节,double
占用8字节,InnerS
占用4字节,为了满足8字节对齐,InnerU
后面需要填充4字节,InnerS
后面也需要填充4字节。所以sizeof(OuterS)=24
字节。
- 内存对齐规则在嵌套结构中的作用:
- 结构体
InnerS
:按照最大成员short
的2字节对齐方式,char
成员后面填充1字节,使得整个结构体大小为4字节,满足2字节对齐。 - 联合体
InnerU
:联合体所有成员共享同一块内存,大小为最大成员的大小,所以InnerU
大小为4字节。 - 结构体
OuterS
:以double
的8字节对齐方式对齐。InnerU
先占用4字节,为了满足8字节对齐,后面填充4字节;double
占用8字节;InnerS
占用4字节,为了满足8字节对齐,后面再填充4字节,最终OuterS
大小为24字节。当union
嵌套在struct
中时,union
的大小就是其最大成员的大小,在整个struct
中参与内存对齐计算,就如同union
是一个普通的具有特定大小的成员一样。
- 结构体
- 优化内存布局方案:
- 调整成员顺序,将
double
放在开头,因为它是最大的成员,这样可以减少填充字节。修改后的代码如下:
- 调整成员顺序,将
struct InnerS {
short s1;
char c1;
};
union InnerU {
long l1;
InnerS s2;
};
struct OuterS {
double d1;
InnerU u1;
InnerS s3;
};
- 此时
sizeof(OuterS)
:double
占用8字节,InnerU
占用4字节,InnerS
占用4字节,InnerU
和InnerS
总共8字节,满足8字节对齐,不需要额外填充,所以sizeof(OuterS)=16
字节。这样通过合理调整成员顺序,在保持数据访问正确性的同时,减小了OuterS
的大小。