• ベストアンサー

コンパイラの違いについて

私は今まで,"BorlandC++5.5.1"を使用してコマンドラインで実行していたのですが,あるプログラムが実行時に問題が発生->処理中断となる. 原因不明のエラーが出ました.  メモリ関係の問題と考え,手をつくしたのですがうまくいかず友人のg++でコンパイル->実行すると"free() invalid pointer"と出ました. もう,にっちもさっちもいかないので試しに"Visual C++2008 体験版"でビルド->実行すると動きました. 一応ちゃんと動いているようなのですが,なぜかわからず気持ち悪いのです…. 最適化の差なのでしょうか? どなたかお答いただけませんか? ちなみに,質問板の利用は初めてです.長文失礼しました.

質問者が選んだベストアンサー

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.6

>すいません… >3と4の意味が少し分かりません. >よろしければ参考になるURL,書籍などを教えていただけませんか? 3.に関してはBorlandC++5.5.1を使ったことが無いのでコンパイルオプションが不明なのですが、コンパイラによってはデバッグビルド時に配列の添え字が上限と下限を超えてないか自動チェックしてくれるコード埋め込んでくれるものが存在します。無い場合は、自分で配列操作時に添え字をチェックするプログラムを埋め込みます。関数やマクロにすると楽だと思います。 4.はTurbo Debugger5.5でブレークポイントを使います。データの変化でブレークできると思いますので確認してみてください。 >代入をする部分でなく,代入をする関数を呼んだ瞬間に問題が発生します. 代入する関数でallocやfreeを使っているんでしょうか?もし違ったら、そう見えるだけかもしれません。それとvectorクラスの参照時に添え字が範囲オーバーしていないか確認してみてください。 ともかく仕事でプログラムをやっていると他の人の作ったとんでもないバグに遭遇することがあります。特にスレッド等が絡むと厄介ですね。他の人の作ったバグを一週間ぐらい追いかけて直したことがあります。それよりは楽だと思いますので諦めず地道にやりましょう。

konboi_bon
質問者

お礼

Turbo Debugger5.5.初めて使いました. 情けないことにブレークの仕方がわからなかったので とりあえずRUNさせてみましたところ, Stopped on exception trhow と表記され,例外処理してるらしいところ を教えてくれました. void Vector::cleanup()という微小要素を0にする関数内の vectorの要素の絶対値が0より大きいか判定する if文の手前で止まってるらしいです. デバッガについて調べつつ,地道に急いでやってみます. 何度も有難うございます.

すると、全ての回答が全文表示されます。

その他の回答 (6)

  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.7

>Turbo Debugger5.5.初めて使いました. これを使うくらいならTurboC++かVC++EEを使ったほうが効率は良いですよ。 http://www.asahi-net.or.jp/~qb3k-kwsk/rpg/program/tool/tcpp/tcpp.html

konboi_bon
質問者

お礼

>これを使うくらいならTurboC++かVC++EEを使ったほうが効率は良いですよ。 あ~確かにそっちの方が楽そうです。 ちょっと考えます。 処理の流れや変数の値を見ていった結果 何となくわかってきましたので、怪しい範囲の数値計算 をおってみます。 最初は訳がわからなかったですが、 皆さんのおかげで、だいぶ分かってきました。 本当にありがとうございます。

すると、全ての回答が全文表示されます。
回答No.5

その症状は「確実にメモリを破壊」しています。 Visual C++2008 体験版で「問題なく動いている」理由は「Visual C++2008 体験版でコンパイルした場合、破壊されるメモリ領域が、他に何の影響も及ぼさない、未使用メモリ領域だから」でしょう。 なので「ちょっとプログラムを変えただけ」で「破壊されるメモリ領域の場所が変わってしまい、Visual C++2008 体験版でコンパイルしても駄目になってしまう」でしょう。 で、誰がメモリを壊しているか調べる為に「どこまで実行できたか」のデバッグ用のprintf表示などを挿入すると、壊れるメモリの位置が変わって異常終了が発生しなくなり、ちゃんと動いてしまったりする。 ちゃんと動いてしまったので、もう大丈夫かと思い、デバッグ用のprintf表示などを削ると、壊れるメモリの位置がまた変わってしまい、異常終了が再発生するようになってしまったりする。 そんな訳で「誰が悪さをしているか?」は、追いかけるのが非常に大変ですが「悪さをしている奴が居るのは確実」なので、頑張って駆逐して下さい。

konboi_bon
質問者

お礼

なるほど… 自分は大学の研究でプログラムを書いているのですが, あまりメモリのことまで考えていませんでした. 今回初めて,自分で一から少し大きいプログラムを書き出した もので,プログラムのデリケートさを始めて実感しました. 締め切りも近いですが,「悪さしている奴を追いかけます」. 回答有り難う御座いました.

すると、全ての回答が全文表示されます。
回答No.4

こんにちは。 >free() invalid pointer 既出のとおり、どこかの変数を操作したときにメモリ破壊したか、このポインタがすでにfree()されているかもしれません。 異常がないコンパイラでコンパイルした場合は、破壊した先のポインタは何の役目がないためだったかもしれません。 >最適化の差なのでしょうか? 自分は、HPのUNIXソースをLinuxに移植した時に、「動いたはずのソースが動かない」と壊滅的な被害を被った経験があります。 このときはLinuxのデバッガを使い、デバッガで異常終了したときのスタックを見ながら1つ1つ潰していきました。 (デバッガによっては見られないのかな…) 根気いるかもしれませんが、頑張ってください。

konboi_bon
質問者

補足

ありがとうございます. デバッガについて色々調べて,デバックしてみます. 今まで,こういう経験をしたことがないので, デバッガ等をつかったことがないのです…

すると、全ての回答が全文表示されます。
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.3

何にしてもバグが有るにも関わらず動いていただけだと思います。確実にハングする今の状態であれば逆にプログラマにとって幸運ですよ! 世の中なぜ落ちるか分らないタイミングで落ちるバグの方が多いから、それに比べりゃ凄くラッキイなんだと思いましょう。 バグの取り方。 1.落ちる操作が分っているのなら、そのアクションから関連するプログラムの部分に表示を埋め込んでどこまで実行できたか確認する。 2.freeしたメモリを指すポインタがあれば、ポインタはNULLにしておく。 3.配列はオーバーガードを自分でプログラムに埋め込むか、コンパイラのオプションでガードできるならそちらに任せる。 4.破壊されている部分が分ったらデバッガでそこを書き換えるプログラムをブレークする。

konboi_bon
質問者

お礼

回答ありがとうございます. 落ちる場所は一応わかっています. 先達が作ったvectorクラスのvector型の要素から double型の配列の要素へ値を代入する部分で エラーが発生しているんだと思います. 代入をする部分でなく,代入をする関数を呼んだ 瞬間に問題が発生します. すいません… 3と4の意味が少し分かりません. よろしければ参考になるURL,書籍などを教えていただけませんか?

すると、全ての回答が全文表示されます。
  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.2

配列のオーバーラン等でメモリー破壊を起こしているのでないかと思います。 VC++2008EEは最適化が出来ないからパディング領域が多めに取られるはず。 BCCでもデバックオプション(-v)を付けてコンパイルすれば一見正しいような動きをするのではないでしょうか。

konboi_bon
質問者

お礼

回答ありがとうございます. あっているかわかりませんが, bcc32 -v -tWC -w ファイル1 ファイル2… でコンパイルしてみたのですが駄目でした.

すると、全ての回答が全文表示されます。
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

ポインタの開放をしてしまった後にそのポインタを使ったとか VC++ではたまたまその開放したポインタの領域を破壊する前に使ったので実行できた などが考えられます

konboi_bon
質問者

お礼

回答ありがとうございます. 今まで,メモリ領域の解放等を考えていなかったので これからは考えていこうとおもいます… やはりこのままではマズイですよね.

すると、全ての回答が全文表示されます。

関連するQ&A