gpt4 book ai didi

pointers - Fortran 90 函数返回指针

转载 作者:行者123 更新时间:2023-12-05 05:26:46 24 4
gpt4 key购买 nike

我看到了这个问题:

Fortran dynamic objects

接受的答案让我质疑我是否安全地编写了以下函数(不允许内存泄漏)

   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 之前已设置(针对此函数),难道不应该关联它吗?我目前遇到内存错误,当我引入一个包含此功能的新模块时,它们开始出现。

非常感谢任何帮助。

我觉得我不够具体。我想制作以下类(class),并知道如何在内存方面安全地实现该类(class)。即:

   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 的参数引用之后,测试 this%vals3D` 的关联状态就没有意义了。如果指针组件未关联(或具有未定义的指针关联状态),则不允许引用它。

此外,如果关联了指针组件,您所做的就是调用停止!

也许您错误地转录了问题的代码?


如果您简单地删除以 if (associated(this%vals3D))... 开头的整个 if 结构,那么您的代码可能有意义。

但是...

  • 如果 this%TF3D 为真,则必须关联 this%vals3D
  • 引用函数时,必须使用指针赋值

    array_ptr => getValues3D(foo)
    ! ^
    ! |
    ! + this little character is very important.

    忘记那个小字符,你正在使用正常分配。语法上有效,在阅读代码时很难找出区别,在这种情况下,除了使用指针的常见陷阱(例如,您需要 DEALLOCATE array_ptr 在你重用它之前或者它超出范围)。这就是返回指针结果的函数被认为有风险的原因。


您的完整代码显示了多个内存泄漏。每次你分配一个 POINTER 的东西时——你几乎需要保证会有一个匹配的 DEALLOCATE。

您的测试代码中有一个循环。 ALLOCATE 经常被调用 - 在 setter 和 getter 中。匹配的 DEALLOCATE 语句在哪里?

关于pointers - Fortran 90 函数返回指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24021039/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com