创建子例程以在主程序中释放数组

Creating a subroutine to deallocate arrays in the main program

我有一个 Fortran 主程序,其中有许多分配的数组。我创建了一个子程序来分配主程序调用的这些数组。我想为解除分配做类似的事情,但我收到编译器错误,说它们未定义为可分配。我最初是这样写代码的:

SUBROUTINE deallocate_jacobian(int3, int4, int5, Diag, Off_Diag_LR, Off_Diag_RL)
use Globals_module,   only : alloc_stat
!--------------------------------------------end of use--------------------------------------------!
integer(i4), intent(in) :: int3, int4, int5
real(dp), intent(inout) ::  Diag(int3, int3, int4),  off_diag_lr(int3, int3, int5), off_diag_rl(int3, int3, int5)
!------------------------------------------end of intents------------------------------------------!
deallocate(Diag,        STAT = alloc_stat)
deallocate(Off_Diag_LR, STAT = alloc_stat)
deallocate(Off_Diag_RL, STAT = alloc_stat)
END SUBROUTINE deallocate_jacobian

然后我这样重写了它:

SUBROUTINE deallocate_jacobian(int3, int4, int5, Diag, Off_Diag_LR, Off_Diag_RL)
use Globals_module,   only : alloc_stat
!--------------------------------------------end of use--------------------------------------------!
integer(i4), intent(in) :: int3, int4, int5
real(dp), allocatable, intent(out) :: Diag(:,:,:),  off_diag_lr(:,:,:), off_diag_rl(:,:,:)
!------------------------------------------end of intents------------------------------------------!
deallocate(Diag,        STAT = alloc_stat)
deallocate(Off_Diag_LR, STAT = alloc_stat)
deallocate(Off_Diag_RL, STAT = alloc_stat)
END SUBROUTINE deallocate_jacobian

编译器错误消失了,但我想知道我是否没有遗漏与可分配意图 inout 相关的更大问题。

首先要提醒 reader 过程的伪参数和过程引用中的实际参数是有区别的。特别是,虚拟参数一般不会 "know" 关于实际参数的事情,除了它对自身的了解。

这就是为什么 Diag 在第一次尝试中不可分配但在第二次尝试中可以分配的原因。

现在,问题询问可分配虚拟参数的更广泛方面。 中有很多问题都涉及到这个问题的一部分,所以我就总结一下有共同点的,有兴趣的可以自己去研究。

  1. 要考虑虚拟参数的分配状态,它必须是可分配的。
  2. 要与可分配的虚拟参数相关联,实际参数必须是可分配的。
  3. 当实际参数和虚拟参数都可分配时,它们的等级必须匹配。
  4. 实际参数和虚拟参数的类型参数,当两者都是可分配的时,必须匹配延迟。
  5. 如果可分配的伪参数具有 intent(out),则实际参数会在调用过程时被释放,伪参数在过程中开始时未分配。
  6. 如果一个可分配的伪参数有 intent(in) 它不能在过程中改变它的分配状态。
  7. 如果可分配的虚拟参数没有 intent(out),那么它与实际参数具有相同的 bounds/extents(而不是通常的 1 索引默认下限)。

我会更明确地说这个。您应该始终检查 alloc_stat 或根本不使用它!

您会看到在第二个片段中所有的释放实际上都失败了。原因可能让您感到困惑。原因是它们 已经被释放

原因是 intent(out) 导致可分配参数的自动释放。