【问题标题】:Variant type storage and alignment issues变体类型存储和对齐问题
【发布时间】:2011-03-24 02:28:05
【问题描述】:

我创建了一个变体类型来代替 boost::variant。我的工作是将当前类型的索引存储在可能类型的列表中,并将数据存储在一个字节数组中,该数组有足够的空间来存储最大的类型。

unsigned char data[my_types::max_size];
int type;

现在,当我向这个变体类型写入一个值时,麻烦就来了。我使用以下内容:

template<typename T>
void set(T a) {
   int t = type_index(T);
   if (t != -1) {
      type = t;
      puts("writing atom data");
      *((T *) data) = a; //THIS PART CRASHES!!!!
      puts("did it!");
    } else {
      throw atom_bad_assignment;
    }
}

崩溃的行是将数据存储到内部缓冲区的行。如您所见,我只是将字节数组直接转换为所需类型的指针。在尝试写入某些值时,这会给我带来错误的地址信号和总线错误。

我在 64 位系统上使用 GCC。如何设置字节数组的对齐方式以确保数组的地址是 64 位对齐的? (或与我可能将此项目移植到的任何架构正确对齐)。

编辑:谢谢大家,但错误出在其他地方。显然,英特尔并不真正关心对齐。对齐的东西更快但不是强制性的,并且程序以这种方式运行良好。我的问题是我在写东西之前没有清除数据缓冲区,这给某些类型的构造函数带来了麻烦。但是,我不会将问题标记为已回答,以便更多人可以给我关于对齐的提示;)

【问题讨论】:

    标签: variant memory-alignment


    【解决方案1】:

    http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Variable-Attributes.html

    unsigned char data[my_types::max_size] __attribute__ ((aligned));
    int type;
    

    【讨论】:

    • 根据编译器的不同,这可能不适用于动态获取的内存。您可能还需要覆盖 operator new 以保证它给您的内存是对齐的。
    【解决方案2】:

    我相信

    #pragma pack(64)
    

    适用于所有现代编译器; it definitely works on GCC.

    更正确的解决方案(不会与全局打包混淆)是:

    #pragma pack(push, 64)
    // define union here
    #pragma pack(pop)
    

    【讨论】:

      猜你喜欢
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-16
      • 2020-11-11
      • 1970-01-01
      • 2017-04-13
      相关资源
      最近更新 更多