1

私は小さなプログラムを開発しましたが、コードの無関係な部分に実際に小さな変更を加えるまでは正常に機能していました。その時点から、プログラムは未処理のwin32例外をスローし、MicrosoftVisualStudioのジャストインタイムデバッガーが起動します。

私はコードブロックを使用していて、私のコンパイラはgccコンパイラです。イライラするのは、gdbを使用してコードブロックからデバッグすることを選択した場合にプログラムが正常に動作することです。これは私には意味がありません。

gdbを使用してデバッグして何が問題なのかを確認できないため(デバッグモードでは正常に実行されるため)、printfsをあちこちに配置してすべてのルートを見つけます。1つの関数で分離しましたが、意味がありません。

bool FileReader::readBitmap(int fileNum)
{
char check;
int dataOffset;
int dataSize;
string fileName;

//used for quick int to string conversion
std::ostringstream stringstream;

stringstream<<fileNum;

string fileNumber = stringstream.str();


fileName = "img"+fileNumber+".bmp";

ifstream stream(fileName.c_str(),ios::in|ios::binary);

stream.read(&check,1);

//checking if it is a bitmap file
if(check != 'B')
    return false;
 stream.read(&check,1);
if(check != 'M')
    return false;

stream.seekg(BMPBPP);
stream.read(&check,1);

//if it is not a monochrome bitmap
if(((int)check) != 1)
    return false;//quit


//get the dataoffset
stream.seekg(DATAOFFSET);
stream.read(&check,1);

dataOffset = (int)check;

//get the data size in bytes
stream.seekg(DATASIZEINBYTES);
stream.read(&check,1);

dataSize = (int)check;

//if this is the first image we read
if(firstImageRead)
{
    //allocate the image buffer
    imgBuffer = (char*) malloc(dataSize);

    //and make sure it does not get re-allocated
    firstImageRead = false;
}


//get the actual bitmap data
stream.seekg(dataOffset);
stream.read(imgBuffer,dataSize);


stream.close();
return true;

}

-大きな編集:問題が何であるかを見つけようとして、ifstreamを関数からクラスのプライベートメンバーに移動しました。また、この関数は、stream.open()を使用してファイルを開くこととまったく同じようになりました。

今では問題なく動作します。したがって、問題はどういうわけか...関数内で使用されるだけではなく、関数内で毎回初期化されるifstreamにあります。それでも...意味がなく、これは発生しないはずです。

私はここで何が問題だったのかを知ることに本当に興味がありますか?

正直なところ、これが何に起因するのか誰かが知っていますか?

4

4 に答える 4

1

調査すべきいくつかのポイント:

  • firstImageReadに初期化されtrueますか?
  • コードの残りの部分はどれくらいの大きさかわからないimgBufferので、さらなる処理はおそらくバッファの終わりを超えて読み取っています。コードの残りの部分は、読み取るデータの量をどのように決定しますimgBufferか?
  • いずれdataSizeかの画像が最初の画像よりも大きい場合は、imgBuffer小さすぎます。
  • 位置で読んだ文字がDATASIZEINBYTESたまたまネガティブな場合は、malloc()約2GBにしようとします。

補足:画像サイズとして1バイトしか読み取らないというのは正しいですか?画像はそんなに小さいですか?

于 2009-06-08T23:07:30.677 に答える
0

ファイルが存在し、ストリームから読み取っていることは確かですか?

そのグローバル 'imgBuffer' についてはどうですか。

こんにちは。入力していただきありがとうございます。残念ながらファイルは存在し、このバッファが解放されるのはプログラムの最後だけです。それを空にしてtrueを返すだけなので、この関数でなければなりません。、プログラムは正常に実行されます...しかし、入力がありません(ファイルが読み取られません)。

バッファーに十分なスペースを割り当てていることを確認してください。malloc() は、この関数を初めて呼び出すときにのみ呼び出されることに注意してください。最初に dataSize が 1000 で、次のファイルで 2000 バイトを読み取りたい場合、dataSize は 2000 になりますが、バッファは 1000 バイトにしか割り当てられません。

于 2009-06-08T22:35:24.407 に答える
0

問題が何であるかを見つけたので、私は自分の質問に答えているだけです。ほとんどの人が推測したように、実際には +1 だけ範囲外に出ているポインター インデックスでした。見つけるのが非常に困難だったのは、デバッガーがまったく別の方向を示していたことです。

これは、クラスにプライベートメンバーをもう1つ追加すると問題が「修正」された理由も説明しています。fileReader オブジェクトにより多くのメモリを割り当て、境界外への書き込みは、追加のプライベート メンバーが占有するメモリに書き込み、未処理の例外を引き起こしませんでした。

これらすべてから何を学べるでしょうか。インデックスを設定するときは非常に注意してください....まあ、これが私に起こったのはこれが初めてではないので:)

于 2009-06-10T09:49:44.593 に答える
0

失敗の例外とコールスタックを示していただけると助かります。

私の推測では、共有違反があり、ファイルを閉じる前にもう一度開いています。早期に終了した場合、ファイルは閉じられていません。

于 2009-06-08T22:25:32.243 に答える