2

この回答で定義されている乱数ジェネレーターを実装しようとしています。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();
}

なんらかの理由で、コンパイルするモードによっては、上記の場所でエラーが発生します。ただし、メンバー変数とコンストラクターをコメントアウトして、代わりに静的変数を使用すると、すべてが機能します。これが正しいコードである場合、リンクで異なるように表示された理由がわかりません。また、いずれにせよ、エラーが発生する理由がわかりません。

4

4 に答える 4

4

*prand を使用していますが、prand を初期化していません。

于 2011-12-15T08:36:58.620 に答える
2

これは、prandポインターが割り当てられることはなく、使用されるだけであるためです。変数を使用する場合static、データメンバーはアクセスされないため、バス エラーは発生しません。メイン関数でポインターに有効な値を確実に割り当てる必要があります。このような

rng2 * prand = new rng2();
于 2011-12-15T08:36:21.880 に答える
2

prandワイルド ポインターです。

変化する:

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();
}
于 2011-12-15T08:37:18.743 に答える
2
rng2 * prand;

これが本当のコードだと完全に確信していますか? このポインターを初期化せず、後で逆参照していないことを考えると、エラーは明らかです。

于 2011-12-15T08:38:26.793 に答える