MST

星途 面试题库

面试题:C++ 中 struct 和 union 在复杂嵌套结构及内存对齐优化中的应用

考虑以下复杂的C++ 结构体和联合体嵌套的情况: ```cpp struct InnerS { short s1; char c1; }; union InnerU { long l1; InnerS s2; }; struct OuterS { InnerU u1; double d1; InnerS s3; }; ``` 1. 计算 `sizeof(InnerS)`、`sizeof(InnerU)` 和 `sizeof(OuterS)`。 2. 解释内存对齐规则是如何在这些嵌套结构中起作用的,特别是 `union` 嵌套在 `struct` 中的情况。 3. 提出一种优化内存布局的方案,使得 `OuterS` 的大小尽可能小,同时保持数据访问的正确性。
38.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 计算大小
    • 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字节。按照内存对齐规则,结构体 OuterSdouble 的8字节对齐方式对齐。InnerU 占用4字节,double 占用8字节,InnerS 占用4字节,为了满足8字节对齐,InnerU 后面需要填充4字节,InnerS 后面也需要填充4字节。所以 sizeof(OuterS)=24 字节。
  2. 内存对齐规则在嵌套结构中的作用
    • 结构体 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 是一个普通的具有特定大小的成员一样。
  3. 优化内存布局方案
    • 调整成员顺序,将 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字节,InnerUInnerS 总共8字节,满足8字节对齐,不需要额外填充,所以 sizeof(OuterS)=16 字节。这样通过合理调整成员顺序,在保持数据访问正确性的同时,减小了 OuterS 的大小。