我看到了这个问题:
并且接受的答案使我产生疑问:我是否安全地编写了以下函数(不允许内存泄漏)
function getValues3D(this) result(vals3D)
implicit none
type(allBCs),intent(in) :: this
real(dpn),dimension(:,:,:),pointer :: vals3D
integer,dimension(3) :: s
if (this%TF3D) then
s = shape(this%vals3D)
if (associated(this%vals3D)) then
stop "possible memory leak - p was associated"
endif
allocate(vals3D(s(1),s(2),s(3)))
vals3D = this%vals3D
else; call propertyNotAssigned('vals3D','getValues3D')
endif
end function
当我运行代码时会显示此警告,但是this%vals3D
如果以前(对此功能)设置了该代码,是否不应该将其关联?我目前遇到内存错误,当我引入一个带有此功能的新模块时,它们开始出现。
任何帮助是极大的赞赏。
我想我还不够具体。我想编写以下课程,并知道如何在内存方面安全地实现该课程。那是:
module vectorField_mod
use constants_mod
implicit none
type vecField1D
private
real(dpn),dimension(:),pointer :: x
logical :: TFx = .false.
end type
contains
subroutine setX(this,x)
implicit none
type(vecField1D),intent(inout) :: this
real(dpn),dimension(:),target :: x
allocate(this%x(size(x)))
this%x = x
this%TFx = .true.
end subroutine
function getX(this) result(res)
implicit none
real(dpn),dimension(:),pointer :: res
type(vecField1D),intent(in) :: this
nullify(res)
allocate(res(size(this%x)))
if (this%TFx) then
res = this%x
endif
end function
end module
以下代码在哪里测试此模块
program testVectorField
use constants_mod
use vectorField_mod
implicit none
integer,parameter :: Nx = 150
real(dpn),parameter :: x_0 = 0.0
real(dpn),parameter :: x_N = 1.0
real(dpn),parameter :: dx = (x_N - x_0)/dble(Nx-1)
real(dpn),dimension(Nx) :: x = (/(x_0+dble(i)*dx,i=0,Nx-1)/)
real(dpn),dimension(Nx) :: f
real(dpn),dimension(:),pointer :: fp
type(vecField1D) :: f1
integer :: i
do i=1,Nx
f(i) = sin(x(i))
enddo
do i=1,10**5
call setX(f1,f) !
f = getX(f1) ! Should I use this?
fp = getX(f1) ! Or this?
fp => getX(f1) ! Or even this?
enddo
end program
目前,我正在Windows上运行。当我单击CTR-ALT-DLT并查看性能时,“物理内存使用情况”随每次循环迭代而增加。这就是为什么我认为我有内存泄漏的原因。
因此,我想提出一个问题:这是内存泄漏吗?(以上每种情况下,内存都会增加)。如果是这样,有没有办法在仍然使用指针的情况下避免内存泄漏?如果不是,那么正在发生的事情,我应该关注并且有办法降低这种行为的严重性吗?
很抱歉最初的模糊问题。我希望这更重要。
您真的受限于Fortran 90吗?在Fortran 2003中,您将为此使用可分配的函数结果。这样更安全。使用指针函数结果,此代码是否导致内存泄漏取决于您如何引用函数(未显示)。如果必须从过程中返回指针,则通过子例程参数返回它要安全得多。
但...
此功能毫无意义。在上一行中将它作为SHAPE的参数引用后,没有任何必要测试此%vals3D`的关联状态。如果指针组件已取消关联(或具有未定义的指针关联状态),则不允许您引用它。
此外,如果指针组件已关联,则您要做的就是停止呼叫!
也许您没有正确地将代码转录到问题上?
如果只是删除以if开头的整个if构造,if (associated(this%vals3D))...
则您的代码可能有意义。
但...
this%TF3D
为true,则this%vals3D
必须关联。引用该函数时,必须使用指针分配
array_ptr => getValues3D(foo)
! ^
! |
! + this little character is very important.
忘记那个小人物,您正在使用常规作业。语法上有效,在读取代码时很难发现差异,在这种情况下,除了使用指针的常见陷阱(例如,需要取消分配)外,还有可能导致内存损坏或泄漏的源头,直到最坏的时刻才可能被发现在您重用它之前,否则它会超出范围)。这就是为什么返回指针结果的函数被认为具有风险的原因。
您的完整代码显示了几次内存泄漏。每次您分配一个POINTER时,都需要非常保证将有一个匹配的DEALLOCATE。
您的测试代码中有一个循环。分配器在setter和getter中都被称为很多。匹配的DEALLOCATE语句在哪里?
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句