【问题标题】:struct sizeof result not expectedstruct sizeof 结果不是预期的
【发布时间】:2009-12-16 10:49:07
【问题描述】:

我有一个这样定义的结构:

typedef struct _CONFIGURATION_DATA {
    BYTE configurationIndicator;
    ULONG32 baudRate;
    BYTE stopBits;
    BYTE parity;
    BYTE wordLength;
    BYTE flowControl;
    BYTE padding;
} CONFIGURATION_DATA;

现在,据我估计,该结构有 10 个字节长。但是,sizeof 报告它是 16 字节长?有人知道为什么吗?

我正在使用 Windows DDK 中的构建工具进行编译。

【问题讨论】:

  • 强制对齐?
  • 记住:结构的大小可能不等于其成员大小的总和;允许实现在成员之间和最后一个成员之后插入填充。 总是按名称访问成员,而不是按偏移量,因为偏移量可能会在编译器版本和供应商之间发生变化。

标签: c++ struct sizeof


【解决方案1】:

对齐。

使用

#pragma pack(1)

...struct goes here...

#pragma pack()

我还建议对事物进行重新排序,并在必要时使用 RESERVED 字节进行填充,以便更好地对齐多字节整数类型。这将使 CPU 的处理速度更快,代码更小。

【讨论】:

  • 只有在你有充分理由的情况下才这样做——许多架构不允许未对齐的访问(因此编译器将不得不使用字节加载和保存以确保安全)并且大多数会带来性能损失。
  • 是的。但我希望编译器在架构不支持时生成正确的指令来访问未对齐的整数类型。这是访问文件、通信和其他 IO 中的二进制数据的常见模式。相反,如果你没有明确指定对齐方式,我会说避免编写结构,因为它会随着编译器版本/设置而改变。
  • 实际上,我之所以需要这样打包,是因为它被写入套接字,并且通信规范指定了一个 10 字节的消息。
  • @Pavel -- 你可能“期望”编译器做某事,但不能保证它会做!例如,MS VC++ 交叉编译器不会自动生成未对齐类型的指令,您必须使用 __unaligned 声明的指针明确告诉它这样做。
  • @Pavel:我当然不会“期望”那样。你只是被宠坏了,因为你习惯了 x86 硬件。编写在最轻微的刺激下崩溃的程序也是一种“常见模式”。
【解决方案2】:

改变元素的顺序。从 ULONG 开始,然后是 BYTE。这将改善结构在内存中的对齐方式。

【讨论】:

    【解决方案3】:

    这是由于填充,因为在您的平台上,ULONG32 显然必须在 4 字节边界上对齐。由于struct 的开头和结尾显然也必须对齐,所以第一个和最后一个BYTE 将分别填充3 个字节。

    【讨论】:

      【解决方案4】:

      您测量的额外大小是编译器引入的填充。

      假设您正在使用 32 位系统,因此您将在 configurationIndicatorbaudRate 之间有 3 个字节的填充,并且在结构末尾还有 3 个字节的填充。

      【讨论】:

        猜你喜欢
        • 2013-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多