- ベストアンサー
VC++でDeugモードOKで、Releaseモードのみでエラーが出る?
マイクロソフトのVisualC++で テキストデータを処理するプログラミングしています。 (MFCは使っていません。) 使用してたプログラムの 一部の変数をクラス化しました。 数多くのエラーをかいくぐり、 Debugモードでは、 目的の演算を実行することができるようになりました。 ところが、 このプロジェクトをReleaseモードでビルド実行すると、 「trans1.exe の 0x0040d052 でハンドルされていない例外が発生しました : 0xC0000005: 場所 0x2eb11a94 に書き込み中にアクセス違反が発生しました。」 というエラーが出て止まってしまいます。 プロジェクトのプロパティ設定で、 ヒープ領域をDebugモードと 同じにしてみたりしたのですが、 状況は改善されません。 メモリの問題のような気がして、 配列の大きさ等をチェックしましたが、 問題なしでした。 プログラムを他の人が使えるように するためには、 Releaseモードが必要なので困っています。 どなたか、アドバイスかご教示お願いします。 デバッグ方法を教えて頂いても大変助かります。 よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
まずメモリ周りの不具合でしょうね。 Debug 版は各領域の配置間隔に余裕が有るので、少しはみ出した程度 なら平気で動きます。 テキストデータ処理で思い浮かぶチェック事項を挙げてみます。 ・文字列は全て終端 '\0' で止めてあるか Debug 版は各領域の間に余裕が有る為、バッファ外で '\0' を拾って 助かっている可能性が有ります。 ・strcpy, strcat, sprintf 上記またはこれらと同等のAPIで、受け側の大きさは足りているか (バッファサイズは問題無いとのことでしたが…) ・動的バッファのポインタや各種ハンドルを多重解放していないか free や close 系は NULL 以外で実行、実行したらポインタに NULL を代入、としておけば間違いは減りますね。 マルチスレッド環境なら ・共有領域に排他制御が施されているか ・スレッド間で処理順序に依存する部分は同期処理が施されているか ・strtok 等、そのままではマルチで使えない関数を使っていないか 先ずはこんな所かな… 必ず再現する障害のデバッグ方法として、Release 版で手軽なのは トレースログですね。 適当な所に通過確認とバッファの内容確認を兼ねてログやメッセージ ボックスを仕掛けます。 しかし、最初から全体に事細かにログを仕掛けると厳しいです。 コツは処理の中間地点に仕掛けて、それより前半か後半かを特定。 次はまた特定された側の中間にログを…、と段々と囲い込みます。 但し、ログを仕込んだ事で領域の配置が変わり、障害が発生しなく なるという罠も希に有ります。心の片隅にでも留めておいて下さい。
その他の回答 (1)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
Release版でデバッグかな? Release版でもデバッグ情報をもたせることは可能です。 プロジェクトのオプションを変更してみてください。 方法はMSDNライブラリを見るとかいてあるはずです。 #1の方がかかれているように、デバッグビルドですとメモリの確保に余裕がありますが、Release版なら結構詰められますので再現できるかもしれません。 ただし、最適化をしてしまうとデバッグ情報は付加できないので、この方法にも限度はあります。
補足
ご教示ありがとうございます。 Release版でデバッグできるとは知りませんでした。 MSDNとGoogole等で「Release(版)」AND「デバッグ」で 検索してみたのですが、 Release版でデバッグする方法が分かりません。 プロジェクト/プロパティ/リンカ/デバッグ情報で デバッグ情報を持たせるを「はい」等にしてみましたが、 ブレークポイントで止まってくれませんでした。。。。 大変恐れ入りますが、 参考URLを教えて頂ければ助かります。 よろしくお願いします。
お礼
ご教示ありがとうございます。 Debug版とRelease版で そのような違いがあったとは知りませんでした。 ご指摘の点を中心に調べましたところ、 sscanf関数を実行するときに、 バッファが1文字分(NULL文字分) 足りなかったところが見つかり、 配列を大きくしたところ、 うまく解決できました。 本当に、本当に、助かりました。 どうもありがとうございました。