- 締切済み
FORTRAN: WIN SalfordFTN77 → LINUX g77 (セグメントエラー)
今まで、Salford FTN77 を使用していたのですが、 この度、LINUXのg77でプログラムを動かすことになりました。 Salford FTN77で正常に動作していたのですが、g77では、実行時に「セグメント違反」が発生してしまいます。 現在わかっていることを列挙しますと… ・Salford FTN77では、問題なく動作する ・g77で、コンパイルまでは成功する ・Salford FTN77からの書き換えはおそらく成功(同種のプログラムで確認済み) ・プログラムをループ(=50)させているのですが、特定のループ回数(=13)でセグメントエラーになる。 ・エラー前の計算は正しく行われている ・ループ回数(=10)を引き下げると実行可能になる ・ループ毎にファイルのcloseも行っている ・スタックを限界まで引き上げて実行したが、同様のエラーが発生 ・特定のループ回数(=13)から、ある特定の変数(ここでは b)を、表示(write( , ) b )もしくは代入(a=b)しようとするとエラーが発生する。 ・エラーが発生する直前までは、ある特定の変数(b)は正しく出力でき、値に異常もない。 元々、簡単な数値計算をおこなう程度にしかプログラムを扱っていない生粋の初心者です。 ネットでセグメントエラーについて検索し、手当たり次第試してみたのですが、うまくいかず困っています。 ソースは公開できないのですが、何か心当たりのある方は、回答していただけると嬉しいです。 よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- nineexit
- ベストアンサー率100% (8/8)
g77は久しく使っていませんが、参考になれば…。 コンパイルオプションに -fbounds-check を入れてみてはいかがでしょうか? これで領域外参照は防げると思います。 g77のバージョンが古けなければ使えるはずです。 それと、implicit noneがプログラムに入っていなければ、宣言文の前に入れるかコンパイラオプション-Wimplicitを使ってください。 領域外参照の原因の一つに宣言してない変数の使用が考えられます。 gfortranの場合は-fimplicit-noneとなります。 以下のことは質問から多少ずれるかも知れませんが一言。 できれば、プログラムは自由形式で書いた方が良いと思います。 allocateやmoduleの機能はバッファオーバーランを予防してくれます。 >・特定のループ回数(=13)から、ある特定の変数(ここでは b)を、表示(write( , ) b )もしくは代入(a=b)しようとするとエラーが発生する。 もともとのプログラムにwrite文や式を代入すると、メモリ参照の手続きが変わるため、変数に代入されている値が変わることが多々あります。 デバグをするのであれば、gdbを使うことをお勧めします。 ただ、簡単なプログラムであればwrite文でいろいろな値を書き出すデバグ方法(いわゆるprintfデバグ)も強力な手段です。
- lv4u
- ベストアンサー率27% (1862/6715)
>>Salford FTN77では、問題なく動作する ということですので、ソースは目で見た限りは、エラーが無いのでしょうね。 CやC++のマニュアルを読むと、CPUの相違から、「メモリの境界合わせ」問題でセグメントエラーが発生することがあるように書かれています。(「構造体の穴」なんて言われたりします。) ただし、ループの処理で、この問題が発生することは少ないんですが、ロジックによっては発生することがあるかもしれませんね。 fortranは学生時代にちょっとやっただけなので、当たっているかどうか?ですが、構造体で、データのタイプにintやlongとcharの混在があると問題になりやすいです。
- eroermine
- ベストアンサー率18% (83/444)
fortranの場合は配列のオーバーフローですね。 writeはきっかけであって原因ではないと思います。 コンパイルオプション -g を付けて コアダンプしたら gdb ただしそこでエラー行の表示をさせるときっかけになった write を指してしまう。 やはりループ内で配列の index がどんどん繰り上(下)がってるところを見つけないと。
- cametan_42
- ベストアンサー率62% (163/262)
#1さんのと同意見ですね。 ソースをコンパイルしてみれば何か分かるかもしれませんが、「ソースは公開出来ない」と言うのでしたら、やっぱり分からない、としか言いようがないです。 セグメントエラーだ、って事なんで、詳細見るんだったらgdb辺り使ってトレースしてみるのが一番だ、と思います。GNUのFortranってのは確かフロントエンドだけ、なんで、背後は同じGCCでしょう。デバッガ使った方が手っ取り早い、と思いますよ。 gdbの使い方は以下のURLでも参考にしてください。
- Tacosan
- ベストアンサー率23% (3656/15482)
はっきり言わせてもらいますが, 「こんな質問内容で答えられる人はいない」と思ってください. デバッガを使って追いかけるなり, 周囲のよく知っている人に聞くなりして自分で解決してください.