0

リリース実行可能ファイルのみを実行すると(Visual Studioで実行しても問題は発生しません)、プログラムがクラッシュします。「プロセスにアタッチ」機能を使用すると、VisualStudioは次の機能でクラッシュが発生したことを示します。

World::blockmap World::newBlankBlockmap(int sideLen, int h){
    cout << "newBlankBlockmap side: "<<std::to_string((long long)sideLen) << endl;
    cout << "newBlankBlockmap height: "<<std::to_string((long long)h) << endl;
    short*** bm = new short**[sideLen];
    for(int i=0;i<sideLen;i++){
        bm[i] = new short*[h];
        for(int j=0;j<h;j++){
            bm[i][j] = new short[sideLen];
            for (int k = 0; k < sideLen ; k++)
            {
                bm[i][j][k] = blocks->getAIR_BLOCK();
            }
        }
    }
    return (blockmap)bm;
}

これは子クラスから呼び出されます...

World::chunk* World_E::newChunkMap(World::floatmap north, World::floatmap east, World::floatmap south, World::floatmap west
,float lowlow, float highlow, float highhigh, float lowhigh, bool displaceSides){
    World::chunk* c = newChunk(World::CHUNK_SIZE+1,World::HEIGHT);

    for (int i = 0; i < World::CHUNK_SIZE ; i++)
    {
        for (int k = 0; k < World::CHUNK_SIZE ; k++)
        {
            c->bm[i][0][k] = blocks->getDUMMY_BLOCK();
        }
    }

    c->bm[(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    c->bm[(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    c->bm[(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    c->bm[(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();

    return c;

}

どこ...

class World {
public: typedef short*** blockmap;
...

VSが指す線は...

short*** bm = new short**[sideLen];

「プロセスにアタッチ」関数は、ローカル変数を統計します... sideLen = 1911407648 h = 0これは私が予期していなかったものですが、coutはそれぞれ9と30を出力します。

ほとんどの「リリースのみでのクラッシュ」の問題は初期化されていない変数が原因であることに気づいていますが、ここで関連する問題はわかりません。

私が受け取る唯一のエラーメッセージは...WindowsがBlocksProject.exeでブレークポイントをトリガーしました。これは、ヒープの破損が原因である可能性があります

私はこの問題に困惑しています、エラーは何ですか?リリース実行可能ファイルをより適切にデバッグするにはどうすればよいですか?

必要に応じてさらにコードを投稿できますが、コードがたくさんあることを覚えておいてください。

よろしくお願いします。

「そして、コードの2番目のチャンクから呼び出されたWorld :: newBlankBlockmap()が表示されません。– Michael Burr」、そのビットを忘れました。

World::chunk* World::newChunk(int side, int height){
cout << "newChunk side: "<<std::to_string((long long)side) << endl;
cout << "newChunk height: "<<std::to_string((long long)height) << endl;
chunk* ch = new chunk();
ch->bm = newBlankBlockmap(side,height);
ch->fm = newBlankFloatmap(side);
return ch;

}

どこ...

struct chunk {
    blockmap bm;
    floatmap fm;
};

ワールドクラスで定義されているように

4

2 に答える 2

2

コメントがほのめかしていることを繰り返すために:あなたが投稿したものから、あなたはコードがひどく構造化されているようです。のようなトリプルポインタ構造short***はデバッグがほとんど不可能であり、絶対に避ける必要があります。表示されたヒープ破損エラーメッセージは、コードのどこかにメモリアクセスが不良であることを示しています。これは、現在の設定では自動的に見つけることができません。

この時点での唯一のオプションは、バグが見つかるまでコード全体を手動で調べるか、リファクタリングを開始することです。後者は今ではもっと時間がかかるように思えるかもしれませんが、将来このコードを使用する予定がある場合はそうではありません。

リファクタリングの可能なヒントとして、次のことを考慮してください。

  • 値の格納にプレーン配列を使用しないでください。std::vector同様に効果的で、デバッグがはるかに簡単です。
  • プレーンnewとを避けてくださいdelete。STLコンテナとスマートポインタを備えた最新のC++では、プレーンメモリの割り当ては非常にまれな例外的なケースでのみ発生するはずです。
  • アレイアクセス操作は常に範囲チェックしてください。パフォーマンスが心配な場合は、リリースビルドで消えるアサートを使用しますが、デバッグに必要なときにチェックが存在することを確認してください。
  • C ++での3次元配列のモデリングはoperator[]、1次元配列のみをサポートしているため、注意が必要な場合があります。operator()代わりに、任意の数のインデックスを使用できる妥協案を使用することをお勧めします。
  • Cスタイルのキャストは避けてください。それらは非常に予測不可能な場合があります。代わりにstatic_cast、C++キャストを使用してくださいdynamic_castreinterpret_cast定期的に使用reinterpret_castしている場合は、どこかでデザインに間違いがある可能性があります。
于 2012-03-03T10:18:47.637 に答える
0

この行に問題がありますshort*** bm = new short**[sideLen];。メモリはsideLen要素に割り当てられますが、割り当て行bm[i][j][k] = blocks->getAIR_BLOCK();にはサイズがの配列が必要sideLen * sideLen * hです。この問題を解決するには、1行目をに変更するshort*** bm = new short**[sideLen * sideLen * h];必要があります。

于 2012-03-03T10:14:53.897 に答える