R. *_*ani 5 fortran finalizer gfortran
考虑下面的小程序,它重现了我在 mac os 上使用 gfortran gcc 9.2.0 时遇到的分段错误):
module stringmod
type :: str_t
character(len=:), allocatable :: s
contains
final :: finalize
end type str_t
type :: static_t
type(str_t) :: expr(3)
end type static_t
type :: dynamic_t
type(str_t), allocatable :: expr(:)
end type dynamic_t
contains
subroutine finalize ( x )
type(str_t), intent(in out) :: x
if (allocated(x%s)) deallocate(x%s)
end subroutine finalize
end module stringmod
use stringmod
implicit none
type(static_t ), allocatable :: stat(:)
type(dynamic_t), allocatable :: dyna(:)
integer :: i, j, n = 10
allocate(stat(n),dyna(n))
do i = 1, n
allocate(dyna(i)%expr(3))
end do
! No problem when deallocating "dyna":
deallocate(dyna)
! while deallocating "stat"causes a segfault with gfortran (gcc 9.2.0 for mac os)
! (unless the final method is removed from the DT):
deallocate(stat)
end
Run Code Online (Sandbox Code Playgroud)
仅当释放具有 str_t 类型的显式数组成员的 static_t 类型的数组时,才会发生段错误。奇怪的是,它似乎与 str_t DT 的最终方法有关(当我删除此过程时,问题就消失了),但我没有看到原因。
这看起来确实像最终子例程的问题,毕竟删除最终子例程可以消除分段错误。然而,这是 gfortran 中更广泛的一类问题的一个例子。
对于 gfortran 中的问题来说是这样。
对于您的情况,您有一个可用的解决方法:删除实际上在任何时候都没有调用的最终子例程。在更一般的情况下,这可能不是一个选择。无论哪种方式,要做的就是向 GCC 维护者报告此错误(特别是如果您可以使用更高版本的编译器进行测试)。
为什么我说这部分是更广泛的问题?让我们看看如何简化您的代码:
type :: str_t
character, allocatable :: s
end type str_t
type :: dynamic_t
type(str_t), allocatable :: expr
end type dynamic_t
type(dynamic_t), allocatable :: dyna
allocate(dyna)
allocate(dyna%expr)
end
Run Code Online (Sandbox Code Playgroud)
或者
implicit none
type :: str_t
character, allocatable :: s
end type str_t
type :: static_t
type(str_t) :: expr
end type static_t
type(static_t), allocatable :: stat
allocate(stat)
end
Run Code Online (Sandbox Code Playgroud)
两者都没有看到最终确定,但在运行时都出现了(对我来说)分段错误。
如果您想查看问题的程序与此答案之间的联系:关键是组件的延迟长度性质。s
作为显式长度(可分配)标量组件,上面的示例在有或没有最终确定的情况下都会崩溃;作为延迟长度组件完成控制崩溃。