最终程序问题(使用gfortran的段错误)

问题描述 投票:4回答:2

考虑下面的小程序,该程序再现了我用gfortran gcc 9.2.0 for mac os获得的分段错误:

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

仅当取消分配具有str_t类型的显式数组成员的static_t类型的数组时,才会发生段错误。奇怪的是,它似乎与str_t DT的最终方法有关(当我删除此过程时,问题就消失了),但我看不出原因。

fortran gfortran finalizer
2个回答
2
投票
这确实看起来像是最终子例程的问题,在全部删除了最终子例程之后,分割错误就消失了。但是,这是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

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

都没有定型化,但运行时都对我来说存在分段错误。

如果您想查看问题程序与此答案之间的联系:关键是组件s

deferred length性质。作为显式长度(可分配)标量组件,以上示例在有或没有完成的情况下都崩溃了;因为延迟长度的组件完成控制了崩溃。


0
投票
[gcc-9.2似乎还有其他问题

在这种情况下

program optional_test integer :: x, y, z x = 1 y = 2 call add(x, y, z) contains subroutine add(x, y, z, debug) integer, intent(in) :: x, y integer, intent(out) :: z logical, intent(in), optional :: debug if(present(debug) .and. debug) then print *, 'debug mode' end if z = x + y end subroutine add end program optional_test

在执行期间抛出了SIGSEGVgcc-8.3正常工作。
© www.soinside.com 2019 - 2024. All rights reserved.