web-dev-qa-db-ja.com

0xC0000005:アクセス違反の読み取り場所0x00000000

私が取り組んでいるスペースインベーダーゲームで非常に奇妙な問題を抱えています。基本的に、アクセス違反エラーが発生します。

SpaceInvaders.exeの0x5edad442(msvcr100d.dll)で未処理の例外:0xC0000005:アクセス違反の読み取り場所0x00000000。

以下のコードを含めると。 Visual Studioは、デバッグ時に「strcmp.asm」に移動します。 Imはどのコードでもstrcmp()を使用していないことに注意してください。コードに何か問題がありますか、これは私が含めた範囲を超えた問題ですか?助けてくれてありがとう

const char* invarray[] = {"invader0.png", "invader1.png", "invader2.png", "invader3.png", "invader4.png"}; 
int i=0;
//Creates 55 invaders
for (int y=0; y<250; y+=50){
    for (int x=0; x<550;x+=50){
        Invader inv(invarray[y/50], x+50, y+550, 15, 15, 1, false, 250);
        invaders[i] = inv;
    }
}

インベーダーコンストラクター:

Invader::Invader(const char *pic, int x, int y, int w, int h, bool dir, bool des, int point) : MovingObject(pic, x, y, w, h) , direction(dir), destroyed(des), b(0), points(point){};

MovingObjectコンストラクター

MovingObject::MovingObject(const char *pic, int x, int y, int w, int h):picture(pic), positionX(x), positionY(y), width(w), height(h) {};
16
Milk

この行は疑わしいようです:

invaders[i] = inv;

iをインクリメントすることはないので、invaders[0]に割り当て続けます。コードを例に減らしたときにこれが単なるエラーである場合は、実際のコードでiを計算する方法を確認してください。 invadersのサイズを超える可能性があります。

コメントが示唆するように、55 invadersを作成している場合、invadersがこの番号を処理するために正しく初期化されていることを確認してください。

10
Fraser

アクセス違反の読み取り位置0x00000000」は、あなたが ポインタの参照解除 が初期化されていないためにゴミがあることを意味します値。これらのガベージ値は何でもかまいませんが、通常はたまたま0そして、あなたはメモリアドレスから読み取ろうとする0x0。オペレーティングシステムが検出し、実行できないようにします。

配列invaders[]は、あなたがそうあるべきだと思うものです。

また、iを更新することはないようです。つまり、同じInvaderオブジェクトをロケーション0 of invaders[]ループの繰り返しごと。

27
Tneuktippa

ここでの問題は、他のコメントで説明されているように、ポインターが適切に初期化されずに逆参照されていることです。 Linuxなどのオペレーティングシステムは、プロセスの仮想アドレス空間から最下位アドレス(たとえば、最初の32MB:0x00_0000 -0x200_0000)を保持します。これは、この場合のように、ゼロに初期化されていないポインターの参照解除がよくある間違いであるためです。したがって、このタイプの間違いが発生すると、アドレス0x0にあるランダム変数を実際に読み取る代わりに(ただし、適切に初期化された場合にポインターが意図するメモリアドレスではなく)、ポインターは外部のメモリアドレスから読み取られますプロセスの仮想アドレス空間。これにより、ページフォールトが発生し、セグメンテーションフォールトが発生し、プロセスを強制終了するためのシグナルがプロセスに送信されます。そのため、アクセス違反エラーが発生します。

5
Jay Medina