【问题标题】:C bitfields memory usageC 位域内存使用情况
【发布时间】:2011-05-26 17:39:52
【问题描述】:

我需要处理如下形式的一些数据:

typedef struct{
    unsigned n1 : 12;
    unsigned n2 : 12;
    unsigned n3 : 12;
    unsigned n4 :  1;
    unsigned n5 : 35;
} data;

我确保它们总计最多为 9 个字节。
但他们没有.. 将该结构的 9 个字节写入文件并将其读回并不会恢复所有数据,sizeof(data) 返回 16。
这里有什么问题?

【问题讨论】:

  • 填充。无法保证编译器将如何分配这些位和/或在结构后插入多少填充。编译器喜欢在均匀边界上结束数据结构。构成均匀边界的因素取决于几个因素,其中最重要的是处理器架构。

标签: c struct bit-fields


【解决方案1】:

问题是编译器出于效率原因添加了一些填充。

可以覆盖此行为。

有关如何使用 gcc 执行此操作,请参阅 forcing alignment in GCC

有关如何使用 Visual c++ 执行此操作,请参阅:forcing alignment in Visual C++

【讨论】:

    【解决方案2】:

    您的结构有 9 个字节长。编译器将其填充到 16 个字节以更加缓存友好。这可以使用特定于编译器的指令/关键字来关闭(我一般不推荐)。见data structure alignment

    【讨论】:

      【解决方案3】:

      您可以使用 gcc 特定的强制对齐:

      typedef struct{
          unsigned n1 : 12;
          unsigned n2 : 12;
          unsigned n3 : 12;
          unsigned n4 :  1;
          unsigned n5 : 35;
      } data __attribute__((__packed__));
      

      阅读:http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Type-Attributes.html

      【讨论】:

        【解决方案4】:

        这在 36 位计算机上运行得非常好。你忘了告诉我们你有没有这些......

        在更常见的 32 位机器上,使用 9 字节对齐将很难实现。如果创建这些结构的数组,则需要不同的代码来访问地址模 0 和地址模 9 的对象中的字段。

        前三个字段的 12 位必须从不同的unsigneds 收集,并且根据地址不同而不同。

        除非您的硬件具有位寻址功能(或 36 位 CPU),否则其他答案中的打包指令不太可能在这里工作。

        【讨论】:

          猜你喜欢
          • 2017-05-08
          • 2010-10-19
          • 1970-01-01
          • 1970-01-01
          • 2010-10-08
          • 2011-01-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多