【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?

私は今まで,"BorlandC++5.5.1"を使用してコマンドラインで実行していたのですが,あるプログラムが実行時に問題が発生->処理中断となる.
原因不明のエラーが出ました.

 メモリ関係の問題と考え,手をつくしたのですがうまくいかず友人のg++でコンパイル->実行すると"free() invalid pointer"と出ました.
もう,にっちもさっちもいかないので試しに"Visual C++2008 体験版"でビルド->実行すると動きました.
一応ちゃんと動いているようなのですが,なぜかわからず気持ち悪いのです….

最適化の差なのでしょうか?
どなたかお答いただけませんか?

ちなみに,質問板の利用は初めてです.長文失礼しました.

A 回答 (7件)

>すいません…


>3と4の意味が少し分かりません.
>よろしければ参考になるURL,書籍などを教えていただけませんか?
3.に関してはBorlandC++5.5.1を使ったことが無いのでコンパイルオプションが不明なのですが、コンパイラによってはデバッグビルド時に配列の添え字が上限と下限を超えてないか自動チェックしてくれるコード埋め込んでくれるものが存在します。無い場合は、自分で配列操作時に添え字をチェックするプログラムを埋め込みます。関数やマクロにすると楽だと思います。

4.はTurbo Debugger5.5でブレークポイントを使います。データの変化でブレークできると思いますので確認してみてください。

>代入をする部分でなく,代入をする関数を呼んだ瞬間に問題が発生します.
代入する関数でallocやfreeを使っているんでしょうか?もし違ったら、そう見えるだけかもしれません。それとvectorクラスの参照時に添え字が範囲オーバーしていないか確認してみてください。

ともかく仕事でプログラムをやっていると他の人の作ったとんでもないバグに遭遇することがあります。特にスレッド等が絡むと厄介ですね。他の人の作ったバグを一週間ぐらい追いかけて直したことがあります。それよりは楽だと思いますので諦めず地道にやりましょう。
    • good
    • 0
この回答へのお礼

Turbo Debugger5.5.初めて使いました.
情けないことにブレークの仕方がわからなかったので
とりあえずRUNさせてみましたところ,
Stopped on exception trhow
と表記され,例外処理してるらしいところ
を教えてくれました.

void Vector::cleanup()という微小要素を0にする関数内の
vectorの要素の絶対値が0より大きいか判定する
if文の手前で止まってるらしいです.

デバッガについて調べつつ,地道に急いでやってみます.
何度も有難うございます.

お礼日時:2009/01/27 21:56

>Turbo Debugger5.5.初めて使いました.


これを使うくらいならTurboC++かVC++EEを使ったほうが効率は良いですよ。
http://www.asahi-net.or.jp/~qb3k-kwsk/rpg/progra …
    • good
    • 0
この回答へのお礼

>これを使うくらいならTurboC++かVC++EEを使ったほうが効率は良いですよ。
あ~確かにそっちの方が楽そうです。
ちょっと考えます。

処理の流れや変数の値を見ていった結果
何となくわかってきましたので、怪しい範囲の数値計算
をおってみます。

最初は訳がわからなかったですが、
皆さんのおかげで、だいぶ分かってきました。
本当にありがとうございます。

お礼日時:2009/01/28 23:34

その症状は「確実にメモリを破壊」しています。



Visual C++2008 体験版で「問題なく動いている」理由は「Visual C++2008 体験版でコンパイルした場合、破壊されるメモリ領域が、他に何の影響も及ぼさない、未使用メモリ領域だから」でしょう。

なので「ちょっとプログラムを変えただけ」で「破壊されるメモリ領域の場所が変わってしまい、Visual C++2008 体験版でコンパイルしても駄目になってしまう」でしょう。

で、誰がメモリを壊しているか調べる為に「どこまで実行できたか」のデバッグ用のprintf表示などを挿入すると、壊れるメモリの位置が変わって異常終了が発生しなくなり、ちゃんと動いてしまったりする。

ちゃんと動いてしまったので、もう大丈夫かと思い、デバッグ用のprintf表示などを削ると、壊れるメモリの位置がまた変わってしまい、異常終了が再発生するようになってしまったりする。

そんな訳で「誰が悪さをしているか?」は、追いかけるのが非常に大変ですが「悪さをしている奴が居るのは確実」なので、頑張って駆逐して下さい。
    • good
    • 0
この回答へのお礼

なるほど…
自分は大学の研究でプログラムを書いているのですが,
あまりメモリのことまで考えていませんでした.

今回初めて,自分で一から少し大きいプログラムを書き出した
もので,プログラムのデリケートさを始めて実感しました.
締め切りも近いですが,「悪さしている奴を追いかけます」.

回答有り難う御座いました.

お礼日時:2009/01/27 12:51

こんにちは。



>free() invalid pointer
既出のとおり、どこかの変数を操作したときにメモリ破壊したか、このポインタがすでにfree()されているかもしれません。
異常がないコンパイラでコンパイルした場合は、破壊した先のポインタは何の役目がないためだったかもしれません。

>最適化の差なのでしょうか?
自分は、HPのUNIXソースをLinuxに移植した時に、「動いたはずのソースが動かない」と壊滅的な被害を被った経験があります。
このときはLinuxのデバッガを使い、デバッガで異常終了したときのスタックを見ながら1つ1つ潰していきました。
(デバッガによっては見られないのかな…)

根気いるかもしれませんが、頑張ってください。

この回答への補足

ありがとうございます.

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

補足日時:2009/01/27 12:41
    • good
    • 0

何にしてもバグが有るにも関わらず動いていただけだと思います。

確実にハングする今の状態であれば逆にプログラマにとって幸運ですよ!
世の中なぜ落ちるか分らないタイミングで落ちるバグの方が多いから、それに比べりゃ凄くラッキイなんだと思いましょう。

バグの取り方。
1.落ちる操作が分っているのなら、そのアクションから関連するプログラムの部分に表示を埋め込んでどこまで実行できたか確認する。
2.freeしたメモリを指すポインタがあれば、ポインタはNULLにしておく。
3.配列はオーバーガードを自分でプログラムに埋め込むか、コンパイラのオプションでガードできるならそちらに任せる。
4.破壊されている部分が分ったらデバッガでそこを書き換えるプログラムをブレークする。
    • good
    • 0
この回答へのお礼

回答ありがとうございます.
落ちる場所は一応わかっています.

先達が作ったvectorクラスのvector型の要素から
double型の配列の要素へ値を代入する部分で
エラーが発生しているんだと思います.
代入をする部分でなく,代入をする関数を呼んだ
瞬間に問題が発生します.

すいません…
3と4の意味が少し分かりません.
よろしければ参考になるURL,書籍などを教えていただけませんか?

お礼日時:2009/01/27 12:40

配列のオーバーラン等でメモリー破壊を起こしているのでないかと思います。


VC++2008EEは最適化が出来ないからパディング領域が多めに取られるはず。
BCCでもデバックオプション(-v)を付けてコンパイルすれば一見正しいような動きをするのではないでしょうか。
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/01/26 23:59

ポインタの開放をしてしまった後にそのポインタを使ったとか


VC++ではたまたまその開放したポインタの領域を破壊する前に使ったので実行できた

などが考えられます
    • good
    • 0
この回答へのお礼

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

やはりこのままではマズイですよね.

お礼日時:2009/01/26 23:50

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報