为什么结构的 sizeof 不等于每个成员的 sizeof 之和?

新手上路,请多包涵

为什么 sizeof 运算符返回的结构大小大于结构成员的总大小?

原文由 Kevin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 439
2 个回答

这是因为添加了填充以满足对齐约束。 数据结构对齐 会影响程序的性能和正确性:

  • 未对齐的访问可能是一个硬错误(通常是 SIGBUS )。
  • 未对齐的访问可能是一个软错误。
    • 要么在硬件中进行纠正,要么适度降低性能。
    • 或通过软件中的仿真进行纠正,以导致严重的性能下降。
    • 此外,原子性和其他并发保证可能会被破坏,从而导致细微的错误。

这是一个使用 x86 处理器的典型设置的示例(全部使用 32 位和 64 位模式):

 struct X
{
    short s; /* 2 bytes */
             /* 2 padding bytes */
    int   i; /* 4 bytes */
    char  c; /* 1 byte */
             /* 3 padding bytes */
};

struct Y
{
    int   i; /* 4 bytes */
    char  c; /* 1 byte */
             /* 1 padding byte */
    short s; /* 2 bytes */
};

struct Z
{
    int   i; /* 4 bytes */
    short s; /* 2 bytes */
    char  c; /* 1 byte */
             /* 1 padding byte */
};

const int sizeX = sizeof(struct X); /* = 12 */
const int sizeY = sizeof(struct Y); /* = 8 */
const int sizeZ = sizeof(struct Z); /* = 8 */

可以通过对齐对成员进行排序来最小化结构的大小(在基本类型中按大小排序就足够了)(如上例中的结构 Z )。

重要提示:C 和 C++ 标准都声明结构对齐是实现定义的。因此,每个编译器可能会选择不同的数据对齐方式,从而导致不同且不兼容的数据布局。因此,在处理将由不同编译器使用的库时,了解编译器如何对齐数据非常重要。一些编译器具有命令行设置和/或特殊的 #pragma 语句来更改结构对齐设置。

原文由 Kevin 发布,翻译遵循 CC BY-SA 3.0 许可协议

C99 N1256标准草案

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

_6.5.3.4 sizeof 运算符_:

3 当应用于具有结构或联合类型的操作数时,结果是此类对象中的总字节数,包括内部和尾随填充。

_6.7.2.1 结构和联合说明符_:

13 …结构对象内可能有未命名的填充,但不是在其开头。

和:

15 在结构或联合的末尾可能有未命名的填充。

新的 C99 灵活数组成员功能( struct S {int is[];}; ) 也可能影响填充:

16 作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这称为灵活数组成员。在大多数情况下,灵活数组成员被忽略。特别是,结构的大小就像省略了柔性数组成员一样,只是它可能具有比省略所暗示的更多的尾随填充。

附件 J 可移植性问题 重申:

以下是未指定的:…

  • 在结构或联合中存储值时填充字节的值 (6.2.6.1)

C++11 N3337 标准草案

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

_5.3.3 大小_:

2 当应用于一个类时,结果是该类的对象中的字节数,包括将该类型的对象放入数组中所需的任何填充。

_9.2 班级成员_:

指向标准布局结构对象的指针,使用 reinterpret_cast 进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。 [注意:因此,标准布局结构对象中可能存在未命名的填充,但不是在其开头,这是实现适当对齐所必需的。 ——尾注]

我只知道足够的 C++ 来理解注释:-)

原文由 Ciro Santilli OurBigBook.com 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题