创建子例程以在主程序中释放数组
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
在第一次尝试中不可分配但在第二次尝试中可以分配的原因。
现在,问题询问可分配虚拟参数的更广泛方面。 fortran中有很多问题都涉及到这个问题的一部分,所以我就总结一下有共同点的,有兴趣的可以自己去研究。
- 要考虑虚拟参数的分配状态,它必须是可分配的。
- 要与可分配的虚拟参数相关联,实际参数必须是可分配的。
- 当实际参数和虚拟参数都可分配时,它们的等级必须匹配。
- 实际参数和虚拟参数的类型参数,当两者都是可分配的时,必须匹配延迟。
- 如果可分配的伪参数具有
intent(out)
,则实际参数会在调用过程时被释放,伪参数在过程中开始时未分配。
- 如果一个可分配的伪参数有
intent(in)
它不能在过程中改变它的分配状态。
- 如果可分配的虚拟参数没有
intent(out)
,那么它与实际参数具有相同的 bounds/extents(而不是通常的 1 索引默认下限)。
我会更明确地说这个。您应该始终检查 alloc_stat
或根本不使用它!
您会看到在第二个片段中所有的释放实际上都失败了。原因可能让您感到困惑。原因是它们 已经被释放 。
原因是 intent(out)
导致可分配参数的自动释放。
我有一个 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
在第一次尝试中不可分配但在第二次尝试中可以分配的原因。
现在,问题询问可分配虚拟参数的更广泛方面。 fortran中有很多问题都涉及到这个问题的一部分,所以我就总结一下有共同点的,有兴趣的可以自己去研究。
- 要考虑虚拟参数的分配状态,它必须是可分配的。
- 要与可分配的虚拟参数相关联,实际参数必须是可分配的。
- 当实际参数和虚拟参数都可分配时,它们的等级必须匹配。
- 实际参数和虚拟参数的类型参数,当两者都是可分配的时,必须匹配延迟。
- 如果可分配的伪参数具有
intent(out)
,则实际参数会在调用过程时被释放,伪参数在过程中开始时未分配。 - 如果一个可分配的伪参数有
intent(in)
它不能在过程中改变它的分配状态。 - 如果可分配的虚拟参数没有
intent(out)
,那么它与实际参数具有相同的 bounds/extents(而不是通常的 1 索引默认下限)。
我会更明确地说这个。您应该始终检查 alloc_stat
或根本不使用它!
您会看到在第二个片段中所有的释放实际上都失败了。原因可能让您感到困惑。原因是它们 已经被释放 。
原因是 intent(out)
导致可分配参数的自动释放。