- 締切済み
fortranでプログラムをつくったのですが
fortranでプログラムをつくりました。 コンパイルは成功しているのですが、プログラムが途中で止まってしまいます。 そして「segmentation fault」とエラーが出ます。 このエラーは何を意味しているのでしょうか?
- みんなの回答 (5)
- 専門家の回答
みんなの回答
dimensionに余裕を持たせないとfortranはダメなんてことはないですよ。suppercomputerで計算させるときのプログラムはfortranなので。逆にプログラムのどこかで、指定の配列をオーバーして計算をさせていたということは考えられます。
どうなんでしょう?たぶんプログラム文のミスだと思うのですが。 約500×500くらいの情報量なら、g77(Debian:Linux)の駄目コンパイラーでもうちの駄目PCで一日くらいかければ計算できますが。。 (1)spはintegerになっているか確かめる。 (2)何行何列までは計算値がでているか見てみる。 (3)配列宣言で、nvr(1:508,[ここはspの整数値]),elepr(1:512,1:512) としておくと変数のなかの行列は指定された整数値が使えます。 (4)nvr(1,sp(1))=elepr(1,5)という計算がなされているがそれは 自分のしたい計算なのかどうか?elepr(1,1)などは計算に関係しないが それは自分がやりたいことと合っているのかどうか? (5)計算のかかる部分はsublutineにした方が計算速度はあがる (6)実数変数の中の整数値は6.かfloat(6)などにしていないと計算が飛ぶ可能性がある ということを試してみてどうでしょうか?回りませんか? eleprの値はちゃんと出ているんですよね?
プログラムを途中で切ってdatファイルに計算結果を書き出して、 期待した結果どおりに数値計算されているか確かめてみるのも いいかも知れません。 (1)問題となっているdo文の前まででプログラムを切って elepr(i,j)の値が正しいかwrite文で書き出してみる。 (2)問題となっているdo文自体を変えてちゃんと回っているか確かめる。 open(unit=2,file='test.dat',form='formatted') do j=1,512 do i=5,512 nvr((i-4),sp(j))=elepr(i,j) write(2,*)i,j,nvr((i-4),sp(j)),"/n" end do end do close(unit=2)
お礼
回答ありがとうございます。 いろいろwrite文で書き出してみましたところ、do文でデータを読み込む際に指定した数だけデータを読み込んでいないことがわかりました。 しかし、なぜこのようになるかわかりません。 メモリーなどが関係しているのでしょうか? 何かわかることがあったら教えてください。
- ametsuchi
- ベストアンサー率31% (81/257)
下で専門家の方が的確な答えを出されているので、補足だけ。 現象よりも 1.何故そうなったか? 2.どこでそうなったか? 3.どうしたらいいか? 知った上で正常に動かしたいのでしょ? 1.は専門家も書かれているとおりです。 2.はバッチでもコンパイル時のオプション次第で、デバッガ相当のものを動かし、どういうサブルーチン(または関数)の呼び順でエラーになったか分かるはずです。しかし、メモリ-を破壊しよぼど変な落ち方をしている場合は、それも分からない場合があります。 3.2.でどこでエラーになっているか分かったらそこを修正します。場合によっては、落ちているのはその場所でも、別のところで悪さをした結果、巡り巡ってそこで落ちていることもあります。 メモリーの参照をミスっても「segmentation fault」になるとは限りません。つまり「他人の家」を壊すと怒られるし、壊せないようになっていますが、「自分の家」なら壊しても怒られないのです。「自分の家」でも命令部は壊れないようにする処理系もあったと思います。「他人の家」は壊すだけでなく、見ることも禁止されています。 能書きは兎も角、もし上の方法で分からないなら、ソースコードを丹念に見直してください。ごくまれにコンパイラやランタイムライブラリのバグである場合もありますが、99.9%間違いなくあなたのプログラムの間違いが原因です。
お礼
回答ありがとうございます。 コンパイラはIBM版AIX用fortranコンパイラを使ってます。デバッガ相当のオプションは今調べています。 止まってい部分はどうやらこの命令のようです。 do 35 j=1,512 do 35 i=5,512 nvr((i-4),sp(j))=elepr(i,j) 35 continue 配列の大きさ、整数、実数は大丈夫です。 この部分で止まっているようですが、この命令の前後で不具合があるのでしょうか? プログラムの見直しは何度もしています。
- toysmith
- ベストアンサー率37% (570/1525)
segmentation faoultはメモリ参照ミスによるエラーです。 拡張無しのfortranの場合、一般的に ・配列の添え字の設定ミス ・ファイル入出力時の変数設定ミス ・共有common初期化にcommon配列を利用した時の次元数、要素数が合っていない ・計算型gotoや算術if文で飛び先行番号の数が足りない ・etc... ポインタ型の拡張がある場合 ・ポインタ変数の値が不正 まとめると「アプリケーションのワーク領域、プログラム領域以外のメモリ領域に対する参照」が発生した場合にsegmentation faultとなります。 これは、データ参照時にプログラム領域への参照が発生した場合に起こる処理系もあります。 極端な話、32ビットアドレスでinterger*4の配列の添え字に10億を与えると確実にsegmentation faultが発生します。 プログラムの内容、動作環境が不明なのでこれくらいしかわかりません。
お礼
すいません、補足のところにお礼を書いてしましました。
補足
回答ありがとうございます。 しかしあまり詳しくないので僕にかいてあることがちょっとよくわかりません。 動作環境は IBMのRS6000のバッチシステムを利用しています。 プログラムの内容は 研究で使うデータの並べ替えです。 どの部分でとまっているのかわかりましたが、その命令のどこが間違っているかわかりません。配列の添え字、dimensionも問題ありません。 とりあえず、今自分でわかる情報はこれくらいです。
お礼
再び回答ありがとうございます。 (1)は確認してOKです (4)は自分のやりたい計算です (6)は直しましたが駄目です (2)より read文で1024個データを読み込む部分が599個しか読み込んでいません。ほかでのreadでは26万個近く読み込むはずが18万個程度のデータしか読み込んでいない状況というのがわかりました。 何かわかることありますか?
補足
dimensionのサイズを倍にしてみたら計算が動きだしました。 今までぎりぎりでやっていたのですが・・・・ dimensionに余裕を持たせないとfortranはダメなものなんでしょか?