- 締切済み
VC++6.0 リリース版で異常終了
VC++6.0 Professionalについての質問です。 デバッグ版では正常に動作するのですが、リリース版だと特定の操作で例外処理が発生して止まってしまいます。 特定の操作とは「ファイルを読み込もうとしたとき」と「ある特定の描画処理をOnDrawにさせたとき」の2つです。 デバッガで処理を追ってみましたが、どちらの操作でもソース上で異常終了はしていないようなので問題点がはっきりせず、どこに手をつければいいのやら見当がつきません。 こういうパターンは何が典型的な原因になるのでしょうか。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- ykkw_2001
- ベストアンサー率26% (267/1014)
かなり日数がたっているので、解決したのかもしれませんが・・・ 個別のプログラムについては、全体の流れがわかってないのでなんとも言えませんが、デバッグ方法(プログラムミスの追求方法)として、リリース版の怪しげなところの周辺に何らかの出力(表示や通信など)をつけておく手があります。 もっとも原始的なprintfデバッグです。デバッガなどのお手軽ツールが信用できないとき、とことん追い詰めることができて有効です。(根性は必要ですが) また、変数などの初期化ミスに関しては、VCのコンパイルスイッチでエラーチェックのレベルを上げることでワーニングが表示されるようになると思います。 ご参考まで・・・すでにご存知でしたらオミットしてください。
- cherry3
- ベストアンサー率39% (18/46)
ykkw_2001さんも答えてますが、 デバッグ版とリリース版では、実行時に 未初期化領域(変数)に入る初期値がそれぞれ違うので、 確保した領域や変数など、使用前にしっかりと 初期化することをお勧めします。
補足
ViewやDocなど主要クラスは確認してみましたが変化はありませんでした。 あまり関係のなさそうな他のクラスも一応全てチェックしてみます。 ところで関数に初期化はあるんでしょうか。
- mnabe
- ベストアンサー率33% (427/1283)
ソースを見てみないとはっきりした事は言えませんが、次の事が考えられます。 ・ファイルを読もうとした時。 開こうとした時でないので、ファイルのオープンは成功している物とします。また、各種エラー判定はできていて、オープンが成功している事が条件です。 考えられる原因 排他制御の失敗。リリース環境で、排他制御を他のアプリケーションが行っていてエラーになっている。 もっと初歩的なミスとして、カレントディレクトリの考え方のミス。これは、ファイルオープンに成功していれば考えにくいのですが、デバッグ環境では、カレントディレクトリは保証されていますが、リリース環境では、カレントディレクトリは不定です。このあたりのエラーはよくある話です(まぁエラー判定してあげれば直に解ることですけどね) 画像処理の件 メッセージの順番を固定している。デバッグ環境では、メッセージは順番に来ますが、リリース環境では、メッセージの到達順番は不定のはずです。メッセージ順番に依存した作りになっていませんか? まぁ両方とも、しっかりしたエラー処理を行っていれば回避出来る物です。 エラー処理をしっかり行っているぞぉって事なら、メモリリーク関係でしょうね。でも、それを読み取るには、情報が少なすぎます。
補足
こちらのかたも早々にお答えいただいて助かります。 「ファイルを読み込もうとしたとき」は、ファイルオープンと実際の読み出しの区別を特にしたものではありませんでした。 「ファイルを読み込む操作をしたとき」程度の意味です。すみません。 質問を出したあと、もう少し調べてみたんですが、 AfxGetMainWnd()->SendMessage( WM_COMMAND, MAKEWPARAM( ID_FILE_NEW, 0 ), NULL ); この部分を取り除いてみたら、転ばずにデータの読込に成功しました。 ただその後、期待通りの動作をしてくれないのですが。 ちなみにSendMessageは「Windowsに任意のメッセージを送らせる関数なんだな」ぐらいの認識で、使い方もよく知らずに使っています。 描画処理でこける方は、下の箇所を取り除くと、とりあえず転びはしなくなりました。 ファイルの読込同様、期待通りの動作にはいたりませんが。 pDoc->m_FldStr[xy.y + y][xy.x + x] = cs2; これはViewとなるクラスのOnDrawから呼び出すメンバ関数に記述しています。 pDocは頭に「m_」をつけていませんが(冗長に感じるので)Viewのメンバ変数です。 CXxxxDoc*型で、OnSize内で「pDoc = (CXxxxDoc*)GetDocument();」としてポインタを与えています。 なぜOnSize内かと言うと、OnInitialUpdateなど他の関数内で値を与えようとすると遅すぎるか早すぎるかして、うまく処理できなかったためです。 いろいろ試してみてOnSizeで指定するのが適当のようだと判断しました。ウィンドウサイズは可変なので、問題があるのかもしれませんが。
- ykkw_2001
- ベストアンサー率26% (267/1014)
ひとつの切り口として・・・・ (1)最適化スイッチ(デバッグオプション)により、 プロセス外のメモリにアクセスが表面化した。 (2)メモリの初期化が、ちゃんとできてないのが、 リリース版で表面化した。 ま、私がよくやるのはこれ、ってことですね。
補足
さっそくのご回答、うれしいです。 「メモリの初期化」というのはどういったものでしょうか。変数の初期化とはまた別? 「プロセス外のメモリにアクセス」はポインタで不適切なアドレスを指定している、ということですか? かなりいい加減な知識とスキルでやってるもので、ちょっと何かあるともうお手上げです。
補足
実はまだ解決しておりません。 どうあがいても糸口が見つからず途方に暮れています。 アドバイスして頂いたことはたいがい試してみたんですが……。 もうデバッグ版のまま配布し続けようと思い始めてます。