2016-11-18 59 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 
    procedure, public :: Deallocate 
end type Parser 
contains 
    subroutine ProcessFile(self) 
    ... 
    end subroutine 
    subroutine Deallocate(self) 
    class(Parser) :: self 
    ... 
    end subroutine 
end module Parser_class 

我讀到最後的關鍵字,並改變了類型定義

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 

此外,在主程序我再也沒有call Parser%Deallocate了。終結者現在不會在任何時候被調用。我以某種方式得到這是因爲我從不銷燬或覆蓋Parser對象。但是,我怎麼能做到這一點,或者什麼是處理釋放過程的正確方法?

+0

我加了'end program'。該程序按預期工作(只讀取文本文件)。我只是想知道,如果我使用'調用Parser%Deallocate'的方式是釋放所有數組的正確方法,或者我應該使用終結器來完成。另外的問題是什麼時候確切地敲定了終結者。雖然不能提供一個工作示例,但我對O-O Fortran還是比較陌生的。 – THo

回答

2

在Fortran 2008標準中,最終確定出來的內容在4.5.6.3節中給出。我不會在這裏複製所有的時間,但我會總結。

什麼明顯提到以下從時,是當不是:

如果圖像執行被終止,或者通過一個錯誤(例如,分配失敗),或通過停止 - 語句的執行,錯誤停止-stmt或end-program-stmt,在終止前立即存在的實體尚未最終確定。

這涵蓋了你的程序。 Parser在程序的範圍內,它仍然存在於程序結束時。沒有明顯的其他事情會導致最終確定。

如果Deallocate是這個類型的最後一個過程,那麼這種類型的對象的定型與類型綁定過程的調用有所不同。在最終確定過程中,這個過程是遞歸的:組件和父母本身都需要完成。使用子程序調用時,遞歸必須以某種方式手動出現。

在很多情況下,人們並不關心實體在程序結束時沒有最終確定。畢竟,任何釋放都是操作系統的問題,而不是程序員的問題。但是,有時候其他形式的整理確實是可取的。

真正的定稿可以在某些方面強制。如果檢查下面的列表,可以想到兩個選項:

  • 使Parser對象可以分配並明確地釋放它;
  • 將整個事物包裝在block結構中。

定稿時發生粗略總結:

  • 當有釋放(指針或可分配);
  • 作爲程序啓動與intent(out)論點;
  • 當到達可執行構造或子程序的末尾時,對於未保存的本地對象;
  • 就在內在賦值給變量之前;
  • 函數結果的值完成後。

如果不閱讀文檔的最終形式你要假裝paragraphs 5 and 7 don't exist

+0

感謝您的詳細解釋。我瞭解到,我應該總是釋放所有我分配的內容而不會造成內存泄漏。那已經過時了嗎?因此,不要調用deallocate子例程並讓程序結束就好了。 – THo

+1

如果只是內存釋放,那麼在程序結束時內存泄漏不是問題。它們可能是當指針以某種方式使用時,最終確定[確實會有所幫助](https://stackoverflow.com/q/29038025),但即使這些指針不在程序結束時。 Allocatables通常是「安全的」。 – francescalus

+0

@THO它在使用垃圾收集或引用計數的語言中已經過時。 Fortran的可分配變量是一種非常簡單的引用計數形式,其中count只能是一個。如果不需要釋放內存或將其重新分配給其他內存,則不必顯式釋放可分配變量。 –