【问题标题】:C++ struct containing unsigned char and int bug包含 unsigned char 和 int 错误的 C++ 结构
【发布时间】:2010-05-30 04:17:34
【问题描述】:

好的,我的 C++ 程序中有一个这样的结构:

struct thestruct
{
 unsigned char var1;
 unsigned char var2;
 unsigned char var3[2];
 unsigned char var4;
 unsigned char var5[8];
 int var6;
 unsigned char var7[4];
};

当我使用这个结构时,会在“var6”之前添加 3 个随机字节,如果我删除“var5”,它仍然在“var6”之前,所以我知道它总是在“var6”之前。

但如果我删除“var6”,那么额外的 3 个字节就消失了。

如果我只使用带有 int 的结构,则没有额外的字节。

所以 unsigned char 和 int 之间似乎存在冲突,我该如何解决?

【问题讨论】:

    标签: c++ struct byte


    【解决方案1】:

    编译器可能正在使用其默认对齐选项,其中大小为 x 的成员在可被 x 整除的内存边界上对齐。

    根据您的编译器,您可以使用#pragma directive 来影响此行为,例如:

    #pragma pack(1)
    

    将关闭 Visual C++ 中的默认对齐方式:

    指定用于打包的值(以字节为单位)。 n 的默认值为 8。有效值为 1、2、4、8 和 16。成员的对齐方式将位于 n 或成员大小的倍数,以较小者为准。

    请注意,出于低级 CPU 性能的原因,通常最好尝试对齐您的数据成员,使它们落在对齐的边界上。一些 CPU 架构需要对齐,而其他(例如 Intel x86)可以容忍不对齐而导致性能下降(有时非常显着)。

    【讨论】:

      【解决方案2】:

      您的数据结构为 aligned,因此您的 int 位于字边界上,对于您的目标而言,字边界可能是 32 位或 64 位。
      您可以像这样重新组织您的结构,这样就不会发生这种情况:

      struct thestruct
      {
       int var6;
       unsigned char var1;
       unsigned char var2;
       unsigned char var3[2];
       unsigned char var4;
       unsigned char var5[8];
       unsigned char var7[4];
      };
      

      【讨论】:

      • 对重组结构的好调用,比使用编译器相关的打包编译指示/属性要好得多。
      • 它仍然是实现定义的。
      【解决方案3】:

      你说的是填充字节吗?那不是错误。正如 C++ 标准所允许的,编译器正在添加填充以保留成员 aligned。这对于某些架构是必需的,并且会大大提高其他架构的性能。

      【讨论】:

        【解决方案4】:

        您遇到了字节对齐问题。编译器正在添加填充以对齐字节。请参阅 this 维基百科文章。

        【讨论】:

          【解决方案5】:

          阅读data structure alignment。本质上,根据编译器和编译选项,您将对齐到不同的 2 次幂。

          为避免这种情况,请将多字节项目(int 或指针)移到单字节(有符号或无符号 char)项目之前——尽管它可能仍然存在在你的最后一项之后。

          【讨论】:

            【解决方案6】:

            虽然重新排列您在 struct 中声明数据成员的顺序很好,但应该强调的是,除非您知道,否则使用 #pragmas 覆盖默认对齐方式是一个坏主意正是你在做什么。根据您的编译器和架构,尝试访问未对齐的数据,特别是通过将地址存储在指针中然后尝试取消引用它,很容易产生可怕的总线错误或其他未定义的行为。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-11-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-05-06
              • 2013-06-15
              • 1970-01-01
              • 2011-07-02
              相关资源
              最近更新 更多