【问题标题】:How does Fortran deallocate linked lists?Fortran 如何释放链表?
【发布时间】:2012-02-07 22:02:45
【问题描述】:

我想在 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)

所有嵌套级别也会被释放,还是我需要遍历列表到最深的元素并从最深的元素向上释放?

【问题讨论】:

  • 我已经很长时间没有在 Fortran 中这样做了,但我很确定你必须手动解除分配。如果您只是解除分配头,那么您将丢失引用并发生内存泄漏。
  • 是的。我很害怕那个。不过我必须说,我遇到了麻烦,这句话是什么意思,滚动我自己的垃圾收集?
  • 你不能实现内存管理的fortran。
  • 这是讽刺还是事实陈述?
  • @emiller 保持所有数组可分配。将每个 allocate 语句与一个 deallocate 语句配对。仅在必要或非常方便时使用指针。如果你遵循这三个,你会没事的。 Fortran 强制你跟踪你的记忆,我真的很欣赏 Fortran - 它不鼓励懒惰的编程,让你更好地了解你的程序。很好的问答。

标签: pointers memory-management linked-list fortran


【解决方案1】:

您必须手动解除分配每个节点。这就是“面向对象”之类的风格派上用场的地方。

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

【讨论】:

  • 宾果游戏。 DeleteImpl 方法正是我想要的。这个面向对象的 fortran 是多么的好和整洁。
  • @emiller:它不是面向对象的。它是面向对象的风格。
  • Append 从头到尾扫描整个列表,所以效率很低。最好跟踪尾节点并将新节点附加到它。为什么要区分LinkedListTypeLinkedListEntryType
猜你喜欢
  • 1970-01-01
  • 2013-05-02
  • 2013-10-30
  • 1970-01-01
  • 2020-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
相关资源
最近更新 更多