2

理解できない奇妙な問題に出くわしました。私は C/C++ の専門家ではないので、ご容赦ください。Sprite クラスから派生した Player クラスから派生した NPC クラスがあります。スプライト クラスには setupAnimation 関数が含まれており、テクスチャ上の座標を含む float の配列を割り当てます。配列の各要素はアニメーションのフレームを参照します。これはすべて良好で、正常に動作します。

ただし、ポインターの配列を NPC クラスに追加すると問題が発生します。これらのポインターは Item クラス型です。この配列を追加すると、配列が小さい場合 (テストしたサイズは 10 でした) は問題なく動作しますが、サイズが少し大きい場合 (100 は私がテストしたサイズでした)、前述のテクスチャ座標に float の配列を割り当てるとクラッシュします。テスト済み)。

上記の資料を示すコードの一部を次に示します。

ポインターの Item クラス配列:

    engItem* itsLoot[100]; // With 100 here, the crash occurs as shown below

テクスチャ座標とそれに対応する割り当て:

    GLfloat* itsTextureXData;
    GLfloat* itsTextureYData;

    ...

    animationFile >> frameCount; // Tested, the value is correct

    engDeallocate(getTextureXData(), true); // Works fine
    itsTextureXData = new GLfloat[frameCount]; // This is where the crash occurs

    engDeallocate(getTextureYData(), true);
    itsTextureYData = new GLfloat[frameCount];

このコードの断片は、Sprite クラスから派生するすべてのクラスの基礎です。私が理解できないのは、余分な 90 個のポインターが float の割り当て中に問題を引き起こす理由です。これに付随するちょっとしたソフトウェア情報

OS: Windows Vista 32 ビット、コンパイラ: Visual C++ 9.0、プログラム ランタイム メモリ: ~17,600k、システム メモリ: ~2GB

これを念頭に置いて、メモリが枯渇していることはわかりません。また、ポインターの配列が割り当ての失敗の原因となる方法を関連付けることもできません。前述のように、割り当ては Sprite から派生した他のすべてのクラス (および Sprite 自体) で正常に機能しますが、このポインターの配列が NPC クラスに追加されると、NPC はクラッシュせずにこのテクスチャ データ float 配列を割り当てなくなります。

4

3 に答える 3

6

プログラムのどこかで、何らかのメモリ エラーが発生している可能性があります (配列の末尾を超えて書き込んだ、解放されたメモリに書き込んだなど)。これが発生すると、メモリ割り当てシステムで使用される構造を上書きして、次の割り当てでクラッシュする可能性があります。Valgrindなどのツールを使用してプログラムを実行し、エラーの場所を見つけることが役立つ場合があります。編集: Windows を使用しており、Valgrind は Linux でのみ動作することに気付きました。コードの移植性が十分であれば、Linux と Valgrind を試すのは比較的簡単です。それができない場合は、ウィンドウに代わる適切な Valgrind はありますか? を参照してください。SOで。(残念ながら、それらのほとんどは商用であり、Valgrind のような無料のオープン ソースではないようです。)

これを回避する最善の方法は、配列ではなく、std::vectorまたはなどの C++ コレクションを使用することです。std::listこれらのコレクションを使用する場合は、コピーを最小限に抑えるようにしてください (たとえばconst、元のオブジェクトを変更しない場合は、元のオブジェクトのコピーではなく参照をパラメーターとして使用するなど)。ゲームをしているように見えるので、これは重要です)。

于 2009-07-27T13:45:36.067 に答える
3

あなたが説明する症状は、破損したメモリ割り当てシステムの典型です。おそらくエラーが発生すると言っている場所でエラーが発生するという事実は、重要ではありません。実際のエラーは、ほぼ確実に他の場所にあります。

これが発生する可能性を減らす方法はたくさんありますが、主な方法は、C++ 構文を少し使って C ではなく、C++ でコードを書くことです。自分でやろうとするのではなく、独自のメモリ管理を実行する std::vector などのコレクションを使用します。

于 2009-07-27T13:33:20.543 に答える
0

すでに述べたように、これはメモリ破損のように見えます。

実際のエラーの場所を絞り込むには、デバッグ モードで実行し、CRT がヒープの破損をチェックする頻度を増やしてみてください。

MSDN から引用した次のコードは、CRT が 1024 ごとではなく 16 ヒープ操作ごとにチェックするようにする方法を示しています。

#include <crtdbg.h>
int main( )
{
int tmp;

// Get the current bits
tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);

// Clear the upper 16 bits and OR in the desired freqency
tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF;

// Set the new bits
_CrtSetDbgFlag(tmp);
}

詳細については、MSDN の _CrtSetDbgFlag を参照してください。

于 2009-07-27T15:43:41.767 に答える