ついに夏本番!さぁ、家族でキャンプに行くぞ! >>

fortranの配列宣言について質問です。
下記の様に配列の変数をサブルーチンの内外で宣言することで違いが出てきました。
こういうものなのでしょうか。失礼します。


parameter(ine=4999)
c
call test1(ine) !error
call test2() !OK

stop
end

subroutine test1(ine)
dimension ary1(ine,50)

return
end

subroutine test2()
parameter(ine=4999)
dimension ary1(ine,50)

return
end

このQ&Aに関連する最新のQ&A

配列 FORTRAN」に関するQ&A: fortran 配列実行結果

A 回答 (4件)

着目すべき点は、おそらく二点。



1.もともとFortranは、サブルーチン・関数の引数は参照渡しが基本だそうです。その場合、定数を渡すことができるのか?

 参照渡しというのは、誤解を恐れずに言うと、変数のアドレスを渡すこと。定数には通常アドレスはありません。強いて言うと(これが問題ですが)、変数の場合は変数のセグメントにあるアドレスが渡されますが、定数の場合コードセグメントのアドレスが渡される可能性があります。一般的にはこれは実行時エラーを引き起こします。親切な処理系なら、コンパイル時にエラーで蹴られます。

2.もし、それを受け取ることができたとしたら、次の難関は、配列宣言のサイズを変数で動的に指定できるのか?

 明示的にメモリを確保するアロケート系の処理以外では、通常名前をつけて宣言する変数は、コンパイル時に大きさが決定している必要があります。test1版の配列宣言は、一つ目の引数が、サブルーチンの引数として宣言された変数になっています。
これは実行時まで内容が決まりません。

以上、通りすがりの者Fortranはやったこと無い者ですが、気になった点です。
    • good
    • 0
この回答へのお礼

詳しい解説ありがとうございました。
「つまり、大きさが決まっていない配列を無理やり宣言したため。」ということでしょうか。

エラーの無い方法でコードを書こうと思います。
ありがとうございました。

お礼日時:2011/04/12 20:41

call test1(ine)でエラーとなり、call test2() でエラーにならない理由はおそらく以下の通りです。



まずtest1内の配列ary1は引数としてわたってくるineの大きさに基づくものですので
可変サイズ(実行時までサイズが不明な)配列という扱いになります。
一方でtest2内の配列ary1は固定サイズ(コンパイル時にサイズが既知な)配列
という扱いになり、この違いがtest1ではスタックオーバーフローを引き起こし
test2ではエラーにならないことの理由かと思います。

test1は外部サブルーチンであり引数ineに何が渡って来ても正しく動作する必要があります。
(つまり実行時までtest1内のary1の大きさを決定することができません)
ですのでtest1内のary1の領域は実行時にスタック上に確保されることになりますが
おそらく、ご利用の環境においてのスタックサイズが十分に大きくない事により
スタックオーバーフローが発生しているのではないかと推測されます。

test2ではなぜエラーにならないかという点ですが、test2内において
ary1の大きさ(50x4999)は(実行時まで待つことなく)
コンパイル時に既に決定しています。そのためご利用のコンパイラでは
test2のary1の領域を静的に(スタック上にではないところに)用意しています。
これによりtest2ではスタックサイズに関係なくary1の領域が確保され、よって
エラーが発生しないという事になっているのかと思います。

以上ご参考になれば幸いです。
    • good
    • 0
この回答へのお礼

詳しい解説ありがとうございました。
「つまり、大きさが決まっていない配列を無理やり宣言したため。」ということでしょうか。

エラーの無い方法でコードを書こうと思います。
ありがとうございました。

お礼日時:2011/04/12 20:41

あぁそうだ,


・その「エラー」とやらがいつ出るのか (コンパイル時・実行時・その他 (できるだけ詳しく))
・(あるなら) エラーメッセージを「一字一句そのまま」
も情報としてあるべきでしょう.
    • good
    • 0

処理系は?


その処理系が従っている規格は?
その規格をじっくり読んで, それでも理解できなかったってこと?

この回答への補足

2003年に購入したintelのfortranです。

以前からこういう症状があったのかもう一度確認してみます。

補足日時:2011/04/12 00:07
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QSegmentation Fault (メモリ制限?)

Segmentation Fault (Fortranのプログラム)に関して質問です。


あるデータを処理するプログラムですが、小さなデータの場合問題ないですが、
大きなデータを扱うようになった場合Segmentation Faultとなります。

宣言している配列サイズを超えた部分のアクセスなどでSegmentation
Faultが出ることがあるようですが、どうやらそのような現象ではなく、
メモリ制限にひっかかっている感じがいたします。


エラーが出る部分はどうやらSubroutine内の大きなデータ宣言を
している部分のようです。(下の例ではtest bが表示れる以前に止まります。)

!--------------------------------------------------
subroutine calc_tri( )

implicit none

real*8 data1(3,200000) !<--- ここでエラー -->

write(6,*) 'test b'
!--------------------------------------------------


このような場合、配列データを減らす以外にどのような対策が
あるのでしょうか?
あるいはメモリ制限になりそうなデータ数が分る方法などあります
でしょうか?


環境は
linux (CentOS)
intel Fortran Compiler version 8.0
Mem: 1GB

topコマンドにて Memの使用割り合いは10%にもならないのですが
コンパイラによるメモリ制限などもあるのでしょうか?

subroutine内の配列の宣言はデータ数より多くとっていることは確認しています。

Segmentation Fault (Fortranのプログラム)に関して質問です。


あるデータを処理するプログラムですが、小さなデータの場合問題ないですが、
大きなデータを扱うようになった場合Segmentation Faultとなります。

宣言している配列サイズを超えた部分のアクセスなどでSegmentation
Faultが出ることがあるようですが、どうやらそのような現象ではなく、
メモリ制限にひっかかっている感じがいたします。


エラーが出る部分はどうやらSubroutine内の大きなデータ宣言を
している部分のようです。(下...続きを読む

Aベストアンサー

スタックオーバフローを起こしているのでは。
ulimitとかでスタックサイズを引き上げるか、ALLOCATABLEな配列にしてヒープ領域を使うようにするとか。

Qスタックオーバーフローとは?

スタックオーバーフローを起こす簡単プログラムを作れって、
大学の教授に言われたんですけど、さっぱり分かりません。
コンパイルと実行の仕方しかわからない自分にそんな過酷な課題を・・・
誰か助けてください。
そもそもスタックオーバーフローってなんなんですかね・・・。

Aベストアンサー

スタックオーバーフローについては既に説明があるので、
サンプルプログラム
こんな感じでスタックを浪費するプログラムを作ればいいと思います。
sum(n)は、1~nまでの数値を足し込むプログラムですが、9000あたりでスタックオーバーフローします。
sum(10000)は50005000で、単純に計算すれば、intの範囲で計算できます。
------------------------------------------------------------

public class Calc {
static int sum(int n){
if(n>0)
return n+sum(n-1);
else
return 0;
}
static public void main(String[] argc){
System.out.println(sum(10000));
}
}

QfortranでのNaNについて

お忙しい所、NaNについて回答お願い致します。

fortranでプログラムを使用して数値計算を行っていますが、計算途中で結果がNaNとなり困っています。
NaNは、0で除算を行なったり、負の数の指数を求めようとした時に出る無限大や定義できない値のようなのですが、式を見ても0で除算を行なったり、負の数の指数を求めようとしている所はありません。

もし同じような経験をされて見事解決された方、居られましたらその時の対処法をお聞かせ願えないでしょうか。
何卒よろしくお願い致します。

Aベストアンサー

環境(OSとコンパイラ)がわからないのでできるとは断言できないのですが、
浮動小数点レジスタの制御フラグをいじって、NaNが生成されたときに
例外が起きるようにしておけば、どこでNaNになるのかが絞れるのではないでしょうか?

いずれにしろ、注意深く値の変化を追っていくよりないと思います。

参考URL:http://www.xlsoft.com/jp/products/intel/cvf/docs/vf-html/pg/pg22.htm

Qフォートランのエラーについて(forrtl)

こんにちは.
Fortranのプログラムなのですが,Visial Fortranを使いましてビルドをしまして,実行したところ,計算の途中で,以下の表示がでました.

forttl:severe(157)
Program Exception-access violation

「何だろう?」と思いましてネットで検索をかけてみたら,以下のエラー一覧にぶち当たりました.
http://www.xlsoft.com/jp/products/intel/cvf/docs/vf-html/em/em01_04.htm

「参照権限を持っていない仮想アドレスに書き込み,読み込みを行おうとした」との記述がありますが,「仮想アドレス」とはいったいどのようなものなのかよくわかりません.Fortranの入門書を紐解いてみたのですが,実際の文法のみで,アドレスについて知ることはできませんでした.

お教えいただきたく,よろしくお願いいたします.

Aベストアンサー

こんにちは。

 >オプションを設定して再コンパイルというのは,どうすればよいのでしょうか.また,それをすると何が明らかになるのでしょうか.
 実際のコンパイラ製品の使い方に関しては、付属するマニュアルやヘルプを参照するのが一番良いと思います。
 もし、手元に無いのであれば、下記のサイトを参照してみてください。
  http://www.xlsoft.com/jp/products/intel/cvf/docs/vf-html/cvf_toc.htm
  この、「4.1 コンパイラ・オプション」に意味が載っています。これは、お手持ちの製品のメーカーやバージョンと合致するとは限りませんので、確認してから利用してください。
  「/check:bounds」は実行時に配列の添え字が宣言の範囲を超えたらエラーを出すようにするようです。
  「/warn:argument_checking」関数やサブルーチンの呼び出し側と呼び出される側の引数の不一致を警告するようにするものです。

では。

QFortran90/95の出力方法について

Fortran90/95の出力方法について
Fortran95において,変数の値をwrite文で出力した後に改行しない方法を教えてください.
具体的には次のProgram reiを用いて質問します.
program rei
implicit none
integer i, n
read(*,*) n
do i = 1, n
write(*,*) i
end do
end
このプログラムを実行させnに3を代入すると次のように表示されます.
1
2
3
しかし,私としては次のように改行せずに表示させたいのです.
1 2 3
また,諸事情により配列は使用しません.
プログラムをどのように改良すればよいのでしょうか.教えてください.

Aベストアンサー

先程のURLに「18.3 数値と文字の変換を行う方法」という章がありますが。
数値を文字列に変換しても出力されませんでしょうか?

Qintel fortranのエラーで困ってます.

character chrc*49・・・
real Tmom,Mw,H0・・・
・・・
・・
write(chrc,'(a7,e12.3,a5,f7.2,a12,f6.1)') 'Mo[Nm]=',Tmom*1.e18,' Mw=', Mw,' Depth[km]=', H0
・・・
・・

をコンパイルすると,以下のようなエラーが出ます.

Main/graphics.f(93): error #5082: 構文エラー、END-OF-STATEMENT が見つかりました、 ( <IDENTIFIER> <CHAR_CON_KIND_PARAM> <CHAR_NAM_KIND_PARAM> <CHARACTER_CONSTANT> <INTEGER_CONSTANT> ... の 1 つを指定してください。
write(chrc,'(a7,e12.3,a5,f7.2,a12,f6.1)') 'Mo[Nm]=',Tmom*1.e18,' Mw=', Mw,' Depth[km]=', H0
----------------------------------------------------------------------------------^
コンパイルは Main/graphics.f で異常終了しました (コード 1)。
(矢印の位置はH0の一文字後)

原因がイマイチよく分かりません...
考えられる原因・解決法を教えて頂けると幸いです.
よろしくお願いします.

character chrc*49・・・
real Tmom,Mw,H0・・・
・・・
・・
write(chrc,'(a7,e12.3,a5,f7.2,a12,f6.1)') 'Mo[Nm]=',Tmom*1.e18,' Mw=', Mw,' Depth[km]=', H0
・・・
・・

をコンパイルすると,以下のようなエラーが出ます.

Main/graphics.f(93): error #5082: 構文エラー、END-OF-STATEMENT が見つかりました、 ( <IDENTIFIER> <CHAR_CON_KIND_PARAM> <CHAR_NAM_KIND_PARAM> <CHARACTER_CONSTANT> <INTEGER_CONSTANT> ... の 1 つを指定してください。
write(chrc,'(a7,e12.3,a5,f7.2,a12,f6.1)'...続きを読む

Aベストアンサー

ファイルの拡張子が.fであるからfixed-formatだと判断されて,1行あたりの最大文字数が72になっている。
継続行を使って2行に分割するのが吉。

Qフォートランで出力をタブ区切りテキストの形式でしたいのですが

フォートラン95で、タブ区切りテキストとしてファイルに出力したいのですが、そのやり方がわかりません。
以前にも同じような質問があり、それに対する回答がちゃんとありましたが、何分初心者なもので、その回答が良く分かりません。
integer*2 tabc / 2313 /  2313は16進の0909に相当(TAB二文字分)
write (*,'(i,A1,i,A1,i)') i1,tabc,i2,tabc,i3
是非教えてください!
出来れば、一般的な形なものでお願いします!
6列出力したいので!

Aベストアンサー

C JIS FORTRAN (古い)ですが、基本は、同じと思いますので、実数型なら
C 例;   の場合 左端の Cは、コメントの意味
A=10.11
B=1.22
C=123.01
D=555.55
E=666.66
F=0.77
C
C WRITE(6,10) の 6 は、出力装置番号 テキスト形式番号を
C 調べて 変更すること。
C 同様に 10 は、行番号

WRITE(6,10)A,B,C,D,E,F
10 FORMAT(1H,6F7.2)

C F7.2 とは、実数表示で、小数点を含め 7文字を出力します。
C 変数に7文字以下の数字が、入っていれば 切り捨てられずに
C 出力されます。 また、1H は、余白部分を指定します。
C プレビュー画面での余白を指定します。

C 結果は、(注意Δは、空白です。)
C ΔΔΔ10.11ΔΔΔ1.22Δ123.01Δ555.55Δ666.66ΔΔΔ0.77

C または、X を入れると 空白が、挿入されます。
C 2X とか 3X とかにすると 空白が、2個、3個になります。

WRITE(6,10)A,B,C,D,E,F
10 FORMAT(1H,X,F7.2,X,F7.2,X,F7.2,X,F7.2,X,F7.2X,F7.2)
C とすると
C ΔΔΔΔ10.11ΔΔΔΔ1.22ΔΔ123.01ΔΔ555.55ΔΔ666.66ΔΔΔΔ0.77 なります。

C JIS FORTRAN (古い)ですが、基本は、同じと思いますので、実数型なら
C 例;   の場合 左端の Cは、コメントの意味
A=10.11
B=1.22
C=123.01
D=555.55
E=666.66
F=0.77
C
C WRITE(6,10) の 6 は、出力装置番号 テキスト形式番号を
C 調べて 変更すること。
C 同様に 10 は、行番号

WRITE(6,10)A,B,C,D,E,F
10 FORMAT(1H,6F7.2)

C F7.2 とは、実数表示で、小数点を含め 7文字を出力します。
C 変数に7文字以下の数字が、入っていれば 切り捨てられず...続きを読む

Q最大スタックサイズを大きくすることの影響は?

再帰呼び出しを行うプログラムでスタックオーバーフローが発生するようになりました。

そこで最大スタックサイズを変更しようと考えていますが
最大スタックサイズを大きくすることで何か影響があることはあるのでしょうか?

他アプリ等に影響が出ないかを懸念しています。

※最大スタックサイズは最大で16Mらしく、現在は1Mです。
 特に影響がないのであれば最初から16Mにしておけば良いような気もして疑問に思っています。

Aベストアンサー

スレッドごとにスタックが確保されるのでプロセスで使用可能な最大スレッド数が減ります
他プロセスへの影響は起こりえません

QFortran:列数の分からないデータの読み込み

列数の分からないcsvファイルを想定して、配列を用いて読み込むプログラムを作成しようと考えています。

試しに十分に大きい1次元配列を用いてデータを読みこむプログラムを作成したところ
1行目読み込み時に行をまたいでデータを読み込んでしまいました。

なんとか、各行のデータだけを読み取る方法はないでしょうか?

よろしくお願いします。

ちなみにプログラムの内容、入力データ、出力結果は次の通りです。

・プログラム
implicit none
integer a(5),i
open(10,file='a.csv',status='old')
read(10,*)(a(i),i=1,5)
write(*,*)(a(i),i=1,5)
close(10)

・入力データ
    1,2,3,4
    5,6,7,8
    9,1,2,3

・出力結果
    1 2 3 4 5

Aベストアンサー

ちょっと強引かもしれないけど、

implicit none
integer a(5),i
character(80) line
open(10,file='a.csv',status='old')
read(10,'(a)') line
read(line,*,end=1)(a(i),i=1,5)
1 write(*,*)(a(i),i=1,5)
close(10)
end

QFORTRAN 複素数 (実部を取り出す方法)

fortran77で複素数の実部を取り出したいのですが、
関数が存在するかわかりません。どなたか、ご存知の方、
教えてください。虚部は出せました。
FORTRAN77(SALFORD FTN77)を使っています。

確か、fortran90なら real(○+□i)だったと思います。

Aベストアンサー

real() でいいと思いますが。

complex x/(1,2)/
write(*,*) x
write(*,*) real(x)
write(*,*) imag(x)
end


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報