【问题标题】:Memory trouble when deallocating Fortran linked list,释放 Fortran 链表时的内存问题,
【发布时间】:2012-08-31 13:45:46
【问题描述】:

我已经实现了一个用 Fortran 编写的通用链表 (genII.f90),位于 http://fortranwiki.org/fortran/show/Linked+list.

我对其进行了测试,一切正常,除了 LI_Remove_Head 函数似乎没有释放内存这一事实。

我在原始模块中添加了函数 LI_Destruct(见下文),结果相同,它不会释放内存。

SUBROUTINE LI_Destruct(List)  
implicit none
TYPE(List_Type),INTENT(INOUT),TARGET :: List
TYPE(Link_Ptr_Type) :: Link_current, Link_next

Link_next%P =>List%Head%next


do while (associated(Link_next%P))
    Link_current%P => Link_next%P

    Link_next%P => Link_next%P%next
    deallocate(Link_current%P)
end do
end subroutine LI_destruct

我当然想念一些东西,所以我的问题有两个: 1-代码中是否有错误?为什么内存没有被“deallocate”清空?

2- 它是否存在更好且几乎标准的 fortran 通用链表?

我在下面添加了用于测试的简单代码:

PROGRAM test_list

! Defines data and other list(s) and arrays for particles. 

USE Generic_List, ONLY : Link_Ptr_Type,Link_Type,List_Type
USE Generic_List, ONLY : LI_Init_List,LI_Add_To_Head,LI_Add_To_Tail,LI_Get_Head,&
     LI_Remove_Head,LI_Get_Next,LI_Associated,LI_Get_Len, LI_destruct

IMPLICIT NONE

TYPE:: Particle_data
    REAL, dimension(2)   :: pos       !! Coordinate dimensionali 
END TYPE Particle_data 

! Definition of the types necessary for the list
TYPE Particle_Node
  TYPE(Link_Type) :: Link
  TYPE(Particle_data), pointer :: Data  
END TYPE Particle_Node

TYPE Particle_Node_ptr
  TYPE(Particle_Node), pointer :: P
END TYPE Particle_Node_ptr

! Create array of lists in order to allow classify the particles
TYPE(List_Type), allocatable      :: ao_Particle_List(:)
TYPE(Link_Ptr_Type)  :: Link
TYPE(Particle_Node_ptr)  :: Particle_elem

!-------------------------------------------------------------!
!-------------------------------------------------------------!

INTEGER, parameter :: Npart_test = 1000000  ! , nPart
INTEGER :: i,iter,j,item,nBuffer
REAL :: pos(2)

    nBuffer = 5

    IF (ALLOCATED(ao_Particle_List)) DEALLOCATE(ao_Particle_List)
    ALLOCATE(ao_Particle_List(0:nBuffer))  

    ! Init list used for temporary construction
    DO iter=0,nBuffer
        CALL LI_Init_List(ao_Particle_List(iter))
    ENDDO

    DO j=1,NBuffer
        DO i=1,Npart_test
            pos(1)=i*1.0;  pos(2)=j*i

            ALLOCATE(Particle_elem%P); ALLOCATE(Particle_elem%P%Data)   ! Allocate data before store
            Particle_elem%P%Data%pos = pos

            ! Elem is treated and should be put at head of the list ao_Particle_List(item)
            item=j
            Link = TRANSFER(Particle_elem,Link); CALL LI_Add_To_Head(Link,ao_Particle_List(item)) ! STORAGE
        END DO
    END DO

    WRITE(*,*) "List is full, see RAM"; READ(*,*)


    ! Write(*,*) "Destruct list"
    DO iter=0,nBuffer
        CALL LI_Destruct(ao_Particle_List(iter))  
    ENDDO

    IF (ALLOCATED(ao_Particle_List)) DEALLOCATE(ao_Particle_List)
    WRITE(*,*) "List is empty, see RAM";     READ(*,*)

END PROGRAM

谢谢大家, 约翰

【问题讨论】:

  • 你的内存没有被释放的证据是什么?您还问为什么内存没有“清空”。释放不会擦除内存,它只是通知内存管理系统该内存可以重用。
  • 在列表创建后和列表被“破坏”后,我检查了与进程关联的 RAM,并且没有任何变化。当我在一个循环中运行测试时(就像在我的最终应用程序中一样),我看到 RAM 使用率正在上升(直到交换)。当我分配/取消分配其他类型的数据时,我从未注意到 RAM 使用量的增加。

标签: list memory linked-list fortran


【解决方案1】:

好的,问题解决了。由于有传输操作,似乎无法在函数LI_DESTRUCT完成中访问数据。

释放链表的正确方法是(与fortran wiki中的示例略有不同)是:

DO
    Link = LI_Remove_Head(ao_Particle_List)
    IF(.NOT.LI_Associated(Link))EXIT
    User = TRANSFER(Link,User)
!~                 WRITE(6,*)User%P%Data%Index,User%P%Data%User_Stuff
    DEALLOCATE(User%P%Data)
    DEALLOCATE(User%P)
ENDDO

【讨论】:

    猜你喜欢
    • 2012-04-18
    • 1970-01-01
    • 2016-11-23
    • 2014-09-19
    • 1970-01-01
    • 2020-12-04
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多