2012-02-07 9 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) 

するすべてのネストされたレベルも割り当てを解除するか、リストを最も深い要素にトラバースし、最も深い要素から割り振りを解除する必要があります上向き?

+4

よう

使用して、私がFortranでこれをしなかったので、長い時間がかかったが、私はあなたが手動で解放する必要があり、かなり確信しています。頭だけの割り当てを解除すると、参照が失われてメモリリークが発生します。 – ChrisF

+0

はい。私はそれをかなり恐れていました。私は言わなくてはいけません、私は問題を抱えています。フレーズは何ですか、私自身のガベージコレクションを巻き込んでいますか? – EMiller

+0

メモリー管理Fortranは実装できません。 –

答えて

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

+1

@emiller:オブジェクト指向ではありません。それはオブジェクト指向のスタイルです。 –

+0

'Append'は頭から尾までリスト全体を掃除するので、非常に非効率です。テールノードを追跡し、新しいノードを追加する方が良いでしょう。 なぜ 'LinkedListType'と' LinkedListEntryType'を区別するのですか? –

関連する問題