2016-11-18 6 views
1

私はオブジェクトがテキストファイルを解析しています。ここに私のメインのプログラムです:Fortranでオブジェクトを正しくファイナライズする方法は?

program main 
use Parser_class 
implicit none 
type(Parser) :: Parser 
call Parser%ProcessFile('data.txt') 
call Parser%Deallocate 
end program main 

型定義は、私が最終キーワードについて読み、メインプログラムでは、さらに

module Parser_class 
type :: Parser 
contains 
    procedure, public :: ProcessFile 
    final :: Deallocate 
end type Parser 
contains 
    subroutine ProcessFile(self) 
    ... 
    end subroutine 
    subroutine Deallocate(self) 
    type(Parser) :: self 
    ... 
    end subroutine 
end module Parser_class 

に型定義を変更

module Parser_class 
type :: Parser 
contains 
    procedure, public :: ProcessFile 
    procedure, public :: Deallocate 
end type Parser 
contains 
    subroutine ProcessFile(self) 
    ... 
    end subroutine 
    subroutine Deallocate(self) 
    class(Parser) :: self 
    ... 
    end subroutine 
end module Parser_class 

であるIもうcall Parser%Deallocateはありません。ファイナライザはいつでも呼び出されることはありません。私は何とかこれを得るのは、私が決してParserオブジェクトを破壊したり上書きしたりしないからです。しかし、私はこれをどうやってやることができますか、または割り当て解除プロセスを処理する適切な方法は何ですか?

+0

「終了プログラム」を追加しました。プログラムは意図どおりに動作します(テキストファイルを読み込むだけです)。私は 'Call Parser%Deallocate'を使う私の方法が全ての配列の割り当てを解除する正しい方法か、ファイナライザを使って行うべきかどうかを知りたいだけです。追加の質問は、ファイナライザが正確に呼び出されるときです。しかし、実際の例を提供することはできません。私はO-O Fortranをかなり新しくしています。 – THo

答えて

2

Fortran 2008の標準では、ファイナライズについては、4.5.6.3 に記載されています。私はここですべての時間をコピーしませんが、私は要約します。

はっきりしないときに、あるときから、次の言及されているもの:(例えば割り振り失敗)またはストップのstmtの実行により、エラーストップ画像の実行が終了し

場合は、エラーのいずれかによって、 -stmt、またはend-program-stmtの場合、終了直前に存在するエンティティはファイナライズされません。

これはプログラムに適用されます。 Parserはプログラムのスコープにあり、プログラムの最後にはまだ存在します。ファイナライズを引き起こす明らかな他の事はありません。

Deallocateがタイプの最終手順である場合、そのタイプのオブジェクトのファイナライズがタイプバインドされたプロシージャの呼び出しと異なる微妙な方法があります。ファイナライズでは、プロセスは再帰的です。コンポーネントと親はそれ自体がファイナライズの対象になります。サブルーチン呼び出しでは、再帰は何らかの方法で手動で表示される必要があります。

多くの場合、エンティティがプログラムの最後に確定されていないかどうかは気にしません。結局のところ、割り当て解除はオペレーティングシステムの問題であり、プログラマの問題ではありません。しかし、他にも整理整頓が望ましい時期があります。

真のファイナライズはいくつかの点で強制することができます。以下のリストを調べる場合、

  • オブジェクトを割り当てることができ、それを明示的に割り当て解除することができます。
  • block構成で全体を包みます。

ファイナライズが発生したときにぞんざいに要約する:

  • を割り当て解除(ポインタまたは割り当て可能)がありますとき。
  • 手順起動としてintent(out)引数で;
  • 実行可能な構成またはサブプログラムの最後に達したとき、保存されていないローカルオブジェクトの場合。
  • 変数への組み込みの直前。関数の結果の値が終わった後の

あなたが paragraphs 5 and 7 don't existをふりをしたいと思う文書の最終的な形を読んでいない場合は

+0

詳細な説明ありがとうございます。私は、メモリリークを作らないように私が割り当てたすべての割り当てを常に解除しなければならないことを知りました。それは時代遅れですか?だから、deallocateサブルーチンを呼び出さずに、プログラムを終了させて​​も問題ありません。 – THo

+1

メモリの割り当てを解除するだけであれば、プログラム終了時にメモリリークは問題になりません。ポインタが特定の方法で使用されているときに、ファイナライズが本当に助けになるかもしれませんが(https://stackoverflow.com/q/29038025)、これもプログラムの最後ではなくても同じです。割り当て可能なものは一般的に「安全」です。 – francescalus

+0

@THoガベージコレクションや参照カウントを使用する言語では廃止されています。 Fortranの割り当て可能な変数は、countを1にすることができる非常に単純な参照カウントです。メモリを解放したり、別のものに割り当てる必要がなければ、割り当て可能な変数を明示的に解放する必要はありません。 –

関連する問題