過去2日間、私は立ち去ることができないような違反に悩まされてきました。私はブレークポイントを使用してエラーの場所を特定しましたが、すべてのコードをコピーして貼り付けることなく、問題が何であるかを誰かが知ってくれることを願っています-.-
私は得ています
Escape.exeの0x1027cb1a(msvcr100d.dll)での初回例外:0xC0000005:アクセス違反の書き込み場所0xcccccccc。 Escape.exeの0x1027cb1a(msvcr100d.dll)で未処理の例外:0xC0000005:アクセス違反の書き込み場所0xcccccccc。
さて、グーグルですばやく検索すると、何か変わったことが起こっていると思います。すべての検索結果は、実際にはどこも指していないポインタについて説明しています(0xcccccccccはメモリ不足のアドレスですか?)。
私はまだコードでポインターを使用していませんが、どちらの方法でも関数を貼り付けて、例外がスローされる行を指摘します(太字):
void mMap::fillMap(){
for(int i = 0; i <= 9; i++){
for(int z = 0; z <= 19; z++){
Tile t1; // default Tile Type = "NULLTILE"
myMap[i][z] = t1;
}
}
}
これで、myMapはTile型の2D配列になりました。他のクラスを追加してすべてが機能しなくなるまで、数日前にこれを機能させていました。
初期化されていないポインタ、または解放されたメモリに格納されているポインタのいずれか。 cccccccc
が最初で、cdcdcdcd
が2番目だと思いますが、コンパイラ/ライブラリの実装によって異なります。
特定のコードの場合、おそらくmyMap
がまだ割り当てられていないため、myMap[0][0]
は0xcccccccc
へのアクセスを試みます。
myMap
がクラスの始まりであり、クラスポインタが初期化されていない場合もあります。
class mMap
{
Tile myMap[10][20];
public:
void f() { myMap[0][0] = 0; }
};
mMap* what;
what->f(); // what is an invalid pointer
これは、メンバー関数が仮想ではないために発生します。そのため、コンパイラーは実行するコードを認識し、オブジェクトポインターを非表示パラメーターとして渡します。最終的に、コンパイラは次のような計算を発行します。
this + offsetof(Whatever::myMap) + z * sizeof(myMap[0]) + i * sizeof(myMap[0][0])
this
は、初期化されていないため、0xcccccccc
です。明らかに、offsetof
の部分はゼロであり、i
とz
は両方ともループの最初の段階でゼロであるため、メモリアドレスとして0xcccccccc + 0 + 0 + 0
を取得します。
これをデバッグするには、呼び出しスタックを使用して、fillMap
を呼び出した関数を見つけます。次に、メンバーアクセス(->
)に使用されるポインターが由来する関数をチェックインします。
MSVC++およびデバッグモードでは、デバッグメモリアロケータは、未定義の動作のケースを見つける方法として、返されたすべてのメモリを0xccccccccに設定します。おそらく、myMap
、またはmyMap
内のいくつかのポインタを初期化したことはありません。初期化コードにバグがないか確認してください。
自分のクラス型のテーブル要素の文字列値にforループを入力しようとすると、同様のエラーが発生しました。そのテーブルで1000個の要素を宣言したので、次のようなものを配置しました。
for (int i = 0; i <= 1000; i++)
{
TAble[i].name = "Some Guy";
TAble[i].age = 4;
}
残念ながら、文字列の場合と同様に、存在しないfillinf要素がテーブルの要素番号1000であると主張している可能性があります。ループヘッダーを変更し、1000より前の等号を削除することで、これを解決することができました。
存在しないものを呼び出そうとしていないかどうかを確認してください。
この質問で発生するすべての回答とコメントについて、Visual C++のメモリフィルに関する適切なリファレンスを次に示します。