fortran 90递归子程序指针

时间:2014-06-10 02:50:38

标签: pointers recursion memory-leaks fortran fortran90

我有一个子程序,我希望以递归方式调用,但似乎在调用时存在内存泄漏。我已经发布了关于函数中内存泄漏的问题

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)        ENDDO

正如我在之前关于内存泄漏的问题中提到的,这也导致了内存泄漏。有什么我忘记分配?或者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

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

我猜测你的setX(和类似的)程序中你先前的帖子中你分配了作为第一个参数传递的d3对象的一些指针组件。在循环的下一次迭代之前或嵌套调用myCurl3DRTest之前,我没有看到这些指针分配如何与deallocate匹配。根据您尝试做的事情,可以通过拨打nullifyField来提供解除分配。

如果我的猜测是正确的,那么没有那些解除分配,你就会有内存泄漏。

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