Fortran DEALLOCATE

时间:2013-05-08 08:39:50

标签: pointers fortran

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

我目前的做法如下:

SUBROUTINE Cleanup(A)

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

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

END SUBROUTINE

并为每个allocatable调用“Cleanup”。这个问题是我的所有变量都不是维度-1。我有一些最多三维。

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

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

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

感谢。

1 个答案:

答案 0 :(得分:8)

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

  • 从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

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

ALLOCATABLE对象。

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

...
IF (things_have_gone_wrong) DEALLOCATE(object)