Fortran DEALLOCATE

der*_*mai 6 fortran pointers

我正在尝试在Fortran中编写一个小子程序,以便在程序出现错误时释放内存中所有已分配的变量,即无法加载文件或不存在的所需文件.此时,必须终止执行,但不是所有的可分配都必须分配(这取决于错误出现在代码的哪个位置),所以我无法进行清理以释放所有这些.

我目前的做法如下:

SUBROUTINE Cleanup(A)

    REAL(8), ALLOCATABLE, DIMENSION(:) :: A

    IF (ALLOCATED(A)) THEN
        DEALLOCATE(A)
    END IF

END SUBROUTINE
Run Code Online (Sandbox Code Playgroud)

并为每个可分配的人调用"清理".这个问题是我的所有变量都不是维度-1.我有一些最多三维.

我首先考虑为不同的维度编写3个不同的子程序并使用重载,但这似乎不是很优雅.

然后我想到也许我可以传递一个指针而不是实际参数A,但我用Google搜索,似乎你不能通过指针释放目标变量.

有关如何正确执行此操作的任何想法?

谢谢.

Ian*_*anH 9

我对此的处理方法将使用以下组合:

  • 从Fortran 95开始,在过程完成时分配的所有本地未保存的可分配变量将自动解除分配.这是否适用取决于您的DLL的调用方式,因此您是否可以实际构建所有可分配的东西都是未保存的本地文件.

  • 从Fortran 2003开始(或Fortran 95 +可分配TR - 在维护的Fortran编译器中广泛支持此语言级别)传递给INTENT(OUT)可分配伪参数的可分配实际参数将在过程开始执行之前自动释放.问题中的清理例程只需要将伪参数的声明添加为INTENT(OUT),然后就不需要IF测试或DEALLOCATE.您仍然需要为清理所需的每种类型和等级编写例程.

  • 与前面类似,传递给INTENT(OUT)伪参数的派生类型变量的可分配组件将自动解除分配.因此,您可以将所有可分配变量一起收集为派生类型对象中的组件.然后清理只涉及将该对象传递给具有INTENT(OUT)虚拟的过程.INTENT(OUT)此处还将具有默认初始化的组件重置为其"默认"值.也许还需要在此时手动执行其他清理(关闭文件等).

  • 另一种方法,再次使用所有变量作为组件的派生类型,是使派生类型对象本身可分配.当您需要清理时,只需取消分配该对象 - 它的组件将自动解除分配.Fortran 2003允许从此类事件触发最终过程,如果此时还要执行其他其他清理操作.

派生类型方法还可以很容易地让您的DLL支持的多个实例一次独立活动(您只有多个派生类型的对象).

给出的派生类型方法的示例如下:

TYPE MyType
  REAL, ALLOCATABLE :: variable_one(:)
  INTEGER, ALLOCATABLE :: variable_two(:)
  ...
END TYPE MyType
Run Code Online (Sandbox Code Playgroud)

INTENT(OUT)假

TYPE(MyType) :: object
ALLOCATE(object%variable_one(xxx))
ALLOCATE(object%variable_two(yyy))
...
IF (things_have_gone_wrong) CALL Cleanup(object)
...
SUBROUTINE Cleanup(arg)
  TYPE(MyType), INTENT(OUT) :: arg
END SUBROUTINE Cleanup
Run Code Online (Sandbox Code Playgroud)

ALLOCATABLE对象.

TYPE(MyType), ALLOCATABLE :: object
ALLOCATE(object)
ALLOCATE(object%variable_one(...))
ALLOCATE(object%variable_two(...))

...
IF (things_have_gone_wrong) DEALLOCATE(object)
Run Code Online (Sandbox Code Playgroud)

  • 我发现解决此问题的另一种方法是使用预处理器宏:#define清理(A)IF(分配(A))DEALLOCATE(A)调用时,清理完成工作. (2认同)