【问题标题】:C++ Bus error when using `^=` and `<<` on a class member `unsigned long`在类成员 `unsigned long` 上使用 `^=` 和 `<<` 时出现 C++ 总线错误
【发布时间】:2012-01-20 23:27:31
【问题描述】:

我正在尝试实现定义in this answer 的随机数生成器。至少据我所知,关于第一行 static unsigned long x=123456789, y=362436069, z=521288629; 应该如何实现存在一些歧义,因为它显示在函数之外。我假设它是作为一个类成员并因此实现的:

class rng2{

public:    

    unsigned long x, y, z;
    rng2() : x(123456789), y(362436069), z(521288629) {}

    unsigned long xorshf96(void) {          //period 2^96-1

        //static unsigned long x=123456789, y=362436069, z=521288629;

        unsigned long t;
        x ^= x << 16;          //BUS ERROR, debug mode
        x ^= x >> 5;
        x ^= x << 1;

        t = x;
        x = y;                 //SEG FAULT, release mode
        y = z;
        z = t ^ x ^ y;

        return z;
    }

};

int main () 
{
    rng2 rand2;
    rng2 * prand;

    for(long d =0; d < 10000; d++)
        cout << "\n" << (*prand).xorshf96();
}

由于某种原因,这会在指定位置出现错误,具体取决于我使用的编译模式。但是,如果我注释掉成员变量和构造函数并改用静态变量,一切正常。如果这是正确的代码,我看不出为什么它在链接中显示不同,无论哪种方式,我都不知道为什么会发生错误。

【问题讨论】:

    标签: c++ bit-manipulation unsigned binary-operators


    【解决方案1】:

    这是因为prand 指针从未被分配,而只是被使用。当使用static 变量时,不会访问任何数据成员,这就是为什么您不会收到总线错误。您应该明确地在您的主函数中为您的指针分配一个有效值。像这样

    rng2 * prand = new rng2();
    

    【讨论】:

    • 这声明了一个名为 prand 的指向 rng2 的指针,并将它分配给指向 rng2 对象的新实例的指针。应该工作吧?我不明白你的评论。
    【解决方案2】:

    您正在使用 *prand,但没有初始化 prand。

    【讨论】:

      【解决方案3】:

      prandwild pointer

      变化:

      int main () 
      {
          rng2 rand2;
          rng2 * prand;
      
          for(long d =0; d < 10000; d++)
              cout << "\n" << (*prand).xorshf96();
      }
      

      到:

      int main () 
      {
          rng2 rand2;
          rng2 * prand = &rand2;
      
          for(long d =0; d < 10000; d++)
              cout << "\n" << (*prand).xorshf96();
      }
      

      或者更好:

      int main () 
      {
          rng2 rand2;
      
          for(long d =0; d < 10000; d++)
              cout << "\n" << rand2.xorshf96();
      }
      

      【讨论】:

      • 不是悬空的,而是未初始化的。 (悬空通常用于指向已删除内存的指针。)效果(未定义的行为)是一样的。
      【解决方案4】:
      rng2 * prand;
      

      您确定这是真正的代码吗?考虑到您没有初始化此指针并稍后取消引用,错误非常明显。

      【讨论】:

        猜你喜欢
        • 2014-05-20
        • 2015-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-23
        • 1970-01-01
        相关资源
        最近更新 更多