【问题标题】:How can I check if a subroutine has been run before?如何检查之前是否运行过子程序?
【发布时间】:2020-04-20 05:12:09
【问题描述】:

我目前有一个使用 2008 标准的 Fortran 程序,它有一个子例程,如果它是子例程的第一次运行,它会从文件中加载数据。在所有运行中,子例程都会对数据进行插值并返回两个值,但目标是避免从文件中重新加载相同的数据。

最初,我有这样的事情:

module myModel_mod
    use myModelLoader_mod
    use linear_interpolation_module
    implicit none
    contains
    subroutine myModel(A, B, C, modelFile, D, E)
        real :: A, B, C, D, E
        character(len=*) :: modelFile
        type(linear_interp_3d), save :: F, G
        real, dimension(:), allocatable, save :: As, Bs, Cs
        if (.not. allocated(As)) then
            call loadModel(modelFile, As, Bs, Cs)
            .
            .  (processing of loaded data and creation of F and G occurs here)
            .
        end if
        call F%evaluate(A, B, C, D)
        call G%evaluate(A, B, C, E)
    end subroutine
end module

我的模块使用了finterp 库。它为两个值 D 和 E 插入一个 3D 网格数据集。我不得不重写这部分代码来修复内存泄漏,我想修复 AsBs 和 @ 的位置987654325@ 被分配。他们不需要 SAVE 属性;它是我使用的较旧的网格插值实现遗留下来的。但是,如果我删除它,那么根据我的理解,我无法检查是否分配了As 以查看之前是否运行过子程序。

我考虑过创建一个具有 SAVE 属性的逻辑标志变量,该属性在子例程第一次运行时设置,但我相信这仍会导致少量内存泄漏,尽管比我目前拥有的要小得多。

有没有办法以不会导致内存泄漏的方式检查“首次运行”条件?

【问题讨论】:

  • 什么叫做“内存泄漏”?我看不到任何通常称为“内存泄漏”的可能性。
  • 在很多代码中,变量被分配并且没有被释放。结果,在一个程序执行中多次运行主函数(调用此子例程)会连续分配更多内存而不释放它。这里的分配是在if语句的省略部分完成的,这是一组if语句,用于从加载的数据中删除冗余条目。
  • 我建议使数组模块变量并创建一个清理子例程。使用可分配数组的 Bur 不会有真正的内存泄漏。内存总是可以访问的,你不能无限分配。
  • @VladimirF 好的,我知道如何使用模块变量来完成此操作,但是如何始终可以访问内存?子程序中定义的变量不是只能从子程序中访问吗?如果它们没有 save 属性,即使在下一次调用的子例程中也不能访问它们吗?
  • 未保存的本地可分配数组根据 Fortran 95 的规则自动释放。

标签: memory-leaks fortran


【解决方案1】:

Fortran 中的可分配数组不可能发生内存泄漏。未保存的可分配局部变量在退出过程时被释放。得救的保留下来,但不能无限制地增长。您只能分配有限数量的局部可分配变量,这些变量会占用一些内存,但它们不会不受控制地增长。

为了回答你的标题问题,我使用保存逻辑变量的方法,如果是关于分配本地或模块数组,我只使用if (allocated())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多