2012-02-07 43 views
7

我想在Fortran中使用鏈接列表來保存未定義長度的數據數組。Fortran如何取消分配鏈接列表?

我有以下設置:

TYPE linked_list 
    INTEGER :: data 
    TYPE(linked_list) :: next_item => NULL() 
END TYPE 

現在說我創建這樣一個列表:

TYPE(LINKED_LIST) :: example_list 
example_list%data =1 
ALLOCATE(example_list%next_item) 
example_list%next_item%data = 2 
ALLOCATE(example_list%next_item%next_item) 
example_list%next_item%next_item%data = 3 

我的問題是,如果我執行:

DEALLOCATE(example_list) 

將所有的嵌套層次也被釋放,或者我是否需要將列表遍歷到最深的元素並從最深處的元素釋放t向上?

+4

它一直以來我用Fortran這樣做很長一段時間,但我敢肯定,你必須手動解除分配。如果你只是解除頭部分配,那麼你將失去參考併發生內存泄漏。 – ChrisF 2012-02-07 22:04:46

+0

是的。我對此非常害怕。但是我必須說,我遇到了麻煩,那是什麼意思,滾動我自己的垃圾回收? – EMiller 2012-02-07 22:09:14

+0

您無法實施內存管理的fortran。 – 2012-02-07 22:57:36

回答

9

您必須手動釋放每個節點。這就是風格「面向對象」有用的地方。

module LinkedListModule 
    implicit none 
    private 

    public :: LinkedListType 
    public :: New, Delete 
    public :: Append 

    interface New 
     module procedure NewImpl 
    end interface 

    interface Delete 
     module procedure DeleteImpl 
    end interface 

    interface Append 
     module procedure AppendImpl 
    end interface 

    type LinkedListType 
     type(LinkedListEntryType), pointer :: first => null() 
    end type 

    type LinkedListEntryType 
     integer :: data 
     type(LinkedListEntryType), pointer :: next => null() 
    end type 

contains 

    subroutine NewImpl(self) 
     type(LinkedListType), intent(out) :: self 

     nullify(self%first) 
    end subroutine 

    subroutine DeleteImpl(self) 
     type(LinkedListType), intent(inout) :: self 

     if (.not. associated(self%first)) return 

     current => self%first 
     next => current%next 
     do 
      deallocate(current) 
      if (.not. associated(next)) exit 
      current => next 
      next => current%next 
     enddo 

    end subroutine 

    subroutine AppendImpl(self, value) 

     if (.not. associated(self%first)) then 
      allocate(self%first) 
      nullify(self%first%next) 
      self%first%value = value 
      return 
     endif 


     current => self%first 
     do 
      if (associated(current%next)) then 
       current => current%next 
      else 
      allocate(current%next) 
      current => current%next 
      nullify(current%next) 
      current%value = value 
      exit 
      endif 
     enddo 

    end subroutine 

end module 

請注意:這是過去的午夜,我真的不喜歡在瀏覽器窗口編碼。此代碼可能不起作用。這只是一個佈局。

使用這樣

program foo 
    use LinkedListModule 
    type(LinkedListType) :: list 

    call New(list) 
    call Append(list, 3) 
    call Delete(list) 
end program 
+1

賓果。 DeleteImpl方法正是我所需要的。這個面向對象的fortran是多麼好,很整齊。 – EMiller 2012-02-08 03:09:46

+1

@emiller:它不是面向對象的。它是面向對象的風格。 – 2012-02-08 08:58:00

+0

'追加'掃過整個列表,從頭到尾,所以效率很低。跟蹤尾部節點並將新節點追加到尾部節點會更好。 爲什麼區分'LinkedListType'和'LinkedListEntryType'? – 2016-01-22 13:01:32