我有一个子程序,我希望以递归方式调用,但似乎在调用时存在内存泄漏。我已经发布了关于函数中内存泄漏的问题
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
非常感谢任何帮助!
答案 0 :(得分:1)
我猜测你的setX(和类似的)程序中你先前的帖子中你分配了作为第一个参数传递的d3
对象的一些指针组件。在循环的下一次迭代之前或嵌套调用myCurl3DRTest
之前,我没有看到这些指针分配如何与deallocate匹配。根据您尝试做的事情,可以通过拨打nullifyField
来提供解除分配。
如果我的猜测是正确的,那么没有那些解除分配,你就会有内存泄漏。
Fortran 95的语言级别加上可分配的TR将使您的生活变得更加轻松......