回 帖 发 新 帖 刷新版面

主题:内存泄漏问题,求助

The test code is as bellow:

module DataMOD  
  type data  
     real :: x  
     type(data),pointer  :: next=>null()  
   ! contains  
   !   FINAL :: RemoveData  
  end type data  
  
  interface operator(+)  
     module procedure DataAdd  
  end interface operator(+)  
  
  interface assignment(=)  
     module procedure DataAssign  
  end interface assignment(=)  
  
contains  
  
  recursive function DataAdd( d1, d2) result(d)  
    implicit none  
    type(data),intent(in) :: d1, d2  
    type(data)            :: d  
    type(data),pointer  :: pd1, pd2, pd  
  
    d%x = d1%x + d2%x  
    if(associated(d1%next))then  
       call RemoveData(d)  
       allocate(d%next)  
       pd1 => d1%next  
       pd2 => d2%next  
       pd => d%next  
       pd = pd1 + pd2  
    endif  
  end function DataAdd  
  
  recursive subroutine DataAssign(od, id)  
    implicit none  
    type(data),intent(in)  :: id  
    type(data),intent(out) :: od  
    od%x = id%x  
    if(associated(id%next))then  
       call RemoveData(od)  
       allocate(od%next)  
       call DataAssign(od%next, id%next)  
    endif  
  end subroutine DataAssign  
  
  recursive function trans(d) result(od)  
    implicit none  
    type(data),intent(in) :: d  
    type(data)            :: od  
    od%x = d%x + 5.  
    if(associated(d%next))then  
       call RemoveData(od)  
       allocate(od%next)  
       od%next = trans(d%next)  
    endif  
  end function trans  
  
  recursive subroutine RemoveData(D)  
    implicit none  
    type(data) :: D  
    if(associated(D%next)) then  
       call RemoveData(D%next)  
       deallocate(D%next)  
    endif  
    write(*,*)"RemoveData"  
  end subroutine RemoveData  
  
  subroutine ddd  
    ! use DataMOD  
    implicit none  
  
    type(data) :: d1, d2, d, dd  
  
    d1%x = 1.  
    d2%x = 2.  
    allocate(d1%next, d2%next)  
    d1%next%x = 3.  
    d2%next%x = 4.  
  
    d = d1 + d2  
  
    dd = trans(d1)  
    call RemoveData(d1)  
    call RemoveData(d2)  
    call RemoveData(d)  
    call RemoveData(dd)  
  end subroutine ddd  
  
end module DataMOD  
  
  
program test  
  use DataMOD  
    
  call ddd  
  
end program test  

After run in valgrind, the memory leakage errors are:

==6470== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==6470==    at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6470==    by 0x400D42: __datamod_MOD_dataadd (test.f90:28)
==6470==    by 0x400999: __datamod_MOD_ddd (test.f90:82)
==6470==    by 0x400E10: MAIN__ (test.f90:97)
==6470==    by 0x400E46: main (test.f90:95)
==6470== 
==6470== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==6470==    at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6470==    by 0x400B9F: __datamod_MOD_trans (test.f90:55)
==6470==    by 0x4009E6: __datamod_MOD_ddd (test.f90:84)
==6470==    by 0x400E10: MAIN__ (test.f90:97)
==6470==    by 0x400E46: main (test.f90:95)
==6470== 
==6470== LEAK SUMMARY:
==6470==    definitely lost: 32 bytes in 2 blocks
==6470==    indirectly lost: 0 bytes in 0 blocks
==6470==      possibly lost: 0 bytes in 0 blocks
==6470==    still reachable: 0 bytes in 0 blocks
==6470==         suppressed: 0 bytes in 0 blocks

how to avoid these memory leakage without using the FINAL subroutine? how to modified the above code?

回复列表 (共3个回复)

沙发

还是开debug检查数据边界. 这样内存地址怎么看呢? 还是说最后那个数字(test.f90:55)表示溢出代码所在的行?

板凳

是行号。

这个主要是指针用在定义运算符 ,内存不知道如何手动释放,用final subroutine倒是可以自动释放,可惜只有ifort支持。

所以请教如何手动释放。

3 楼

我开始没认真看贴, 不好意思. 
我听dongyuanxun兄讲, fortran本身没有内存回收机制.

我来回复

您尚未登录,请登录后再回复。点此登录或注册