2012-08-31 108 views
1

我已經實現了Fortran語言編寫的一個通用的鏈表(genII.f90)在 http://fortranwiki.org/fortran/show/Linked+list找到。內存重新分配的麻煩Fortran的鏈表時,

我測試,並一切正常,除了一個事實,即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是否有錯誤的代碼?出於什麼原因內存不會被「釋放」清空?

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 

感謝所有, 約翰

+2

你是什麼證據表明內存沒有釋放?你還會問爲什麼內存不「被清空」。釋放內存不會擦除內存,它只是通知內存管理系統內存可供重用。 –

+0

我檢查相關的過程中,RAM創建列表後列表後「破壞」,並沒有改變。當我在一個循環中運行測試時(因爲它在我的最終應用程序中),我發現RAM使用量正在增加(直到交換)。當我分配/取消分配其他類型的數據時,我從不會注意到RAM使用量的增加。 –

回答

0

OK問題就解決了。由於存在傳輸操作,因此完成的功能LI_DESTRUCT中似乎無法達到數據。

解除分配鏈表(如FORTRAN維基的例子略有不同),正確的方法是:

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