3

誰かがここで何が起こっているのかについて何か考えがありますか?

私は得る

Unhandled exception at 0x5081f508 (msvcr100d.dll) in myProgram.exe: 0xC0000005: Access violation writing location 0x041e0010.

この行で:

fscanf(fp, " %lf %lf %lf\n", &vertices[i].x, &vertices[i].y, &vertices[i].z );

プログラムを実行しているときですが、デバッグモード(Visual Studio 2010)でプログラムを実行すると、すべてがうまくいきます。はfscanf()期待どおりにファイルを読み取ります。

例外は実際にはinput.cの行でスローされます。

#else  /* _UNICODE */
       _FASSIGN( longone-1, (char*)pointer , pFloatStr, (char)decimal, _loc_update.GetLocaleT());
#endif  /* _UNICODE */

私が間違っていなければ。そして、私は行の周りのUNICODEについてのこれらのコメントが何を意味するのかわかりません、それがまさに私がそれらをここに含めた理由です。


追加情報

コールスタック:

msvcr100d.dll!_fassign_l(int flag, char * argument, char * number, localeinfo_struct * plocinfo)  Line 258 + 0x6 bytes  C++   

>msvcr100d.dll!_input_l(_iobuf * stream, const unsigned char * format,    localeinfo_struct * plocinfo, char * arglist)  Line 1281 + 0x21 bytes C++

msvcr100d.dll!vfscanf(int (_iobuf *, const unsigned char *, localeinfo_struct *, char *)* inputfn, _iobuf * stream, const char * format, localeinfo_struct * plocinfo, char * arglist)  Line 61 + 0x13 bytes    C

msvcr100d.dll!fscanf(_iobuf * stream, const char * format, ...)  Line 99 + 0x18 bytes   C

myProgram.exe!main(int argc, char * * argv)  Line 166 + 0x49 bytes  C++

myProgram.exe!__tmainCRTStartup()  Line 555 + 0x19 bytes    C

myProgram.exe!mainCRTStartup()  Line 371    C

その他の情報

このプログラムは、OpenGLを使用したシェーディングに関するものでありvertices、呼び出しに表示されるのfscanf()は、次の配列です。

typedef struct _Vertex {
    double  x, y, z;
    int polygonsThisPartOf; // Number of polygons this vertex is a part of
    Point normal;
} Vertex;

私のプログラムの最初のバージョンでは、verticesは配列の配列であり、すべてが正常に実行されました。verticesこの例外は、上記の配列として使用するようにコードを変更した後に発生し始めましたstruct

配列の割り当て

    //                                              ˇ THIS is the mistake
vertices = (Vertex *) malloc(vcount * sizeof(Vertex *));
if (vertices == NULL) exit(-2);

vcount正しいです。

4

3 に答える 3

1

1)「fscanf()」構文は問題ないように見えます。

2)「_UNICODE」メッセージ(ステップインしたMSVC内部)は、すべてのWin32コードの16ビットUnicodeバージョンを使用していることを意味します。これは(8ビットASCII形式の文字列ではなく)16ビットUnicode形式の文字列を想定しています。 )。

これは正常であり、予想されます。Visual Studio内のソースからすべてをコンパイルしている場合、それは問題ではないはずです。

3)配列要素「vertices[i]」が正常に割り当てられていることを確認することに注力します。

提案:

「fscanf()」にブレークポイントを設定し、デバッガーでfscanfを呼び出す前に変数を確認します。

さらに、これをfscanfの前に追加し、ブレークポイントを次のデバッグ行に配置することもできます。

 vertices[i].x = vertices[i].y = vertices[i].z = 0;
于 2012-06-22T19:08:30.477 に答える
1

問題はコードのどこかにあり、fscanf呼び出しに関連していない可能性があります。メモリの場所が、保持できるよりも多くのバイトで書き込まれている可能性があります。デバッグモードで実行すると、必要以上のメモリが割り当てられるため、通常、デバッグモードでエラーが発生することはありませんが、適切なデバッガーは、バッファーの長さを超えて書き込みを行っているときに通知する必要があります。

于 2012-06-22T19:09:39.297 に答える
1

以前は、デバッグビルドで再現されないバグがあった場合、ほとんどの場合、バッファオーバーフローまたは何らかのポインタエラーが発生していました。

デバッグビルドでは、スタックのビルドが少し異なる場合があります。スタックに余分なものがあるかもしれません、そして時々あなたがバッファの終わりを書き留めるとき、書き込みはデバッグのものに入り、明らかに悪いことは何も起こりません。もちろん、これはバッファがスタックに割り当てられていることを前提としています。または、バッファがヒープ内にある場合は、デバッグビルドのヒープに余分なものがある可能性があります(追加の文字列が含まれている可能性があります)。

したがって、変数iをチェックして、配列の最後からインデックスが付けられていないことを確認してください。そして、変数fpをチェックして、それが適切な場所を指していることを確認します。ポインタ演算によって決定された場合は、ポインタの計算が正しいことを確認してください。

デバッグビルドで再現されない場合は、リリースビルドをインストルメント化して、iの値、の値fp、およびその他の情報(fpバッファ内へのポインタの場合、現在のアドレス、そのバッファの現在の長さfp。バッファ内にあるかどうかを確認できます)。

PS私は「Heisenbug」と呼ばれるこの種のバグを聞いたことがあります。デバッグしようとすると、動作が変わります。

于 2012-06-22T19:16:47.667 に答える