【问题标题】:fortran 90 recursive subroutines pointerfortran 90 递归子程序指针
【发布时间】:2014-06-10 02:50:38
【问题描述】:

我有一个想要递归调用的子程序,但是调用的时候好像有内存泄漏。我已经发布了有关函数内存泄漏的问题

Fortran 90 function return pointer

Fortran 90 difference between compaq visual fortran and gfortran

但现在我遇到了一个新问题。我已将所有函数都切换为子例程,现在我在递归调用子例程时遇到了麻烦。这是我的代码(对不起,它不短)

   recursive subroutine myCurl3DRTest(d3,u,v,w,gd,n)
     implicit none
     type(vecField3D),intent(inout) :: d3
     real(dpn),dimension(:,:,:),intent(in) :: u,v,w
     type(griddata),intent(in) :: gd
     integer,intent(in),optional :: n
     type(vecField3D) :: temp1,temp2,temp3,temp4,temp5,temp6
     real(dpn),dimension(:,:,:),allocatable :: dwdy,dvdz
     real(dpn),dimension(:,:,:),allocatable :: dwdx,dudz
     real(dpn),dimension(:,:,:),allocatable :: dvdx,dudy
     real(dpn),dimension(:,:,:),allocatable :: curlx,curly,curlz
     integer :: dummyN
     integer,dimension(3) :: s
     s = shape(u)
     if (.not.present(n)) then 
      dummyN = 1
     else ; dummyN = n ;endif

     call nullifyField(temp1)
     call nullifyField(temp2)
     call nullifyField(temp3)
     call nullifyField(temp4)
     call nullifyField(temp5)
     call nullifyField(temp6)
     call myDel(temp1,w,gd,1,2)
     call myDel(temp2,v,gd,1,3)
     call myDel(temp3,w,gd,1,1)
     call myDel(temp4,u,gd,1,3)
     call myDel(temp5,v,gd,1,1)
     call myDel(temp6,u,gd,1,2)

     allocate(dwdy(s(1),s(2),s(3)))
     allocate(dvdz(s(1),s(2),s(3)))
     allocate(dwdx(s(1),s(2),s(3)))
     allocate(dudz(s(1),s(2),s(3)))
     allocate(dvdx(s(1),s(2),s(3)))
     allocate(dudy(s(1),s(2),s(3)))
     call getY(temp1,dwdy)
     call getZ(temp2,dvdz)
     call getX(temp3,dwdx)
     call getZ(temp4,dudz)
     call getX(temp5,dvdx)
     call getY(temp6,dudy)
     call deleteField(temp1)
     call deleteField(temp2)
     call deleteField(temp3)
     call deleteField(temp4)
     call deleteField(temp5)
     call deleteField(temp6)

     call setX(d3,   dwdy - dvdz  )
     call setY(d3,-( dwdx - dudz ))
     call setZ(d3,   dvdx - dudy  )
     deallocate(dwdy)
     deallocate(dvdz)
     deallocate(dwdx)
     deallocate(dudz)
     deallocate(dvdx)
     deallocate(dudy)
     allocate(curlx(s(1),s(2),s(3)))
     allocate(curly(s(1),s(2),s(3)))
     allocate(curlz(s(1),s(2),s(3)))
     call getX(d3,curlx)
     call getY(d3,curly)
     call getZ(d3,curlz)

     if (dummyN.gt.1) then
        call myCurl3DRTest(d3,curlx,curly,curlz,gd,dummyN-1)
     endif
     deallocate(curlx)
     deallocate(curly)
     deallocate(curlz)
   end subroutine

在主程序中,我有

   do k=1,10**4
     call myCurl3DRTest(f3,u,v,w,gd,1)

!调用 myCurl(f3,u,v,w,gd) 结束

正如我在之前关于内存泄漏的问题中提到的,这也会导致内存泄漏。有什么我忘记分配的吗?还是 curlx、curly 和 curlz 没有从每个级别释放?

很清楚,在 deleteField 内部:

   subroutine deleteField(this)
     implicit none
     type(vecField3D),intent(inout) :: this
     if (associated(this%x)) deallocate(this%x)
     if (associated(this%y)) deallocate(this%y)
     if (associated(this%z)) deallocate(this%z)
     this%TFx = .false.
     this%TFy = .false.
     this%TFz = .false.
   end subroutine

在 nullifyField 内部:

   subroutine nullifyField(this)
     implicit none
     type(vecField3D),intent(inout) :: this
     nullify(this%x); this%TFx = .false.
     nullify(this%y); this%TFy = .false.
     nullify(this%z); this%TFz = .false.
     this%TFNullified = .true.
   end subroutine

非常感谢任何帮助!

【问题讨论】:

    标签: pointers recursion memory-leaks fortran fortran90


    【解决方案1】:

    根据您之前的帖子,我猜测在您的 setX(和类似)过程中,您分配了作为第一个参数传递的 d3 对象的一些指针组件。在循环的下一次迭代之前或在嵌套调用myCurl3DRTest 之前,我看不到这些指针分配如何通过取消分配进行匹配。根据您尝试执行的操作,可能可以通过调用 nullifyField 来提供这些释放。

    如果我的猜测是正确的,那么如果没有这些释放,你就会发生内存泄漏。

    Fortran 95 的语言级别加上可分配的 TR 将使您的生活变得如此轻松......

    【讨论】:

    • 是的,结果证明没有在其中一个子例程中解除分配..我想迁移到 F95,我可能会..
    猜你喜欢
    • 2014-07-24
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    相关资源
    最近更新 更多