关于指针:Fortran DEALLOCATE 您所在的位置:网站首页 allocate的用法Fortran中 关于指针:Fortran DEALLOCATE

关于指针:Fortran DEALLOCATE

2023-11-14 01:38| 来源: 网络整理| 查看: 265

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

我当前的方法如下:

123456789SUBROUTINE Cleanup(A)     REAL(8), ALLOCATABLE, DIMENSION(:) :: A     IF (ALLOCATED(A)) THEN         DEALLOCATE(A)     END IF END SUBROUTINE

并为每个可分配的名称调用"清理"。问题在于,并非我所有的变量都是1维。在其中一些方面,我最多涉及三个方面。

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

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

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

谢谢。

相关讨论 当执行终止时,代码使用的所有资源都会以任何方式自动释放,因此您不必担心显式地对其进行分配。 我知道Fortran会自动释放内存,但是在这种情况下,我正在编写一个从Labview调用的dll,因此这是谁管理内存。 当dll出现错误时,Labview突然停止,并且如果我尝试重新执行,它将显示消息:" Array has beenlocated"并关闭。 这意味着内存未正确释放。 注意:real(8)不能保证为8个字节。 一种可移植的方式是use ISO_FORTRAN_ENV,real (real64)用于64位。

我对此的处理方式将结合使用以下内容:

从Fortran 95开始,过程完成时分配的所有本地未保存的可分配变量将自动释放。这是否适用取决于您的DLL的调用方式,因此取决于您是否可以实际构造事物,以使所有可分配的内容都是未保存的本地变量。

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

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

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

派生类型方法还使一次拥有多个DLL支持的实例的活动独立变得容易(您只有多个派生类型的对象)。

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

12345TYPE MyType   REAL, ALLOCATABLE :: variable_one(:)   INTEGER, ALLOCATABLE :: variable_two(:)   ... END TYPE MyType

INTENT(OUT)虚拟

123456789TYPE(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对象。

1234567TYPE(MyType), ALLOCATABLE :: object ALLOCATE(object) ALLOCATE(object%variable_one(...)) ALLOCATE(object%variable_two(...)) ... IF (things_have_gone_wrong) DEALLOCATE(object) 相关讨论 我发现解决此问题的另一种方法是使用预处理程序宏:#define Cleanup(A)IF(ALLOCATE(A))DEALLOCATE(A)被调用时,Cleanup会完成工作。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有