为什么在堆栈/堆上分配以下Fortran代码取决于派生类型的内容?

问题描述:

我不明白为什么下面的程序如果bar字段存在于containerType中,那么使用SIGSEGV进行段错误,并且如果它被注释掉就没有问题。我使用的是x86_64,使用gfortran-4.4.6和gfortran-4.6.3进行编译。为什么在堆栈/堆上分配以下Fortran代码取决于派生类型的内容?

据我所知,使用指向containerType的指针应该强制分配包含在堆中的大数组,但似乎并非如此。对可执行文件运行valgrind给我

Warning: client switching stacks? SP change: 0x7ff000448 --> 0x7fe0603f8 
     to suppress, use: --max-stackframe=16384080 or greater 

(输出的其余部分是恕我直言不相关的,但如果需要,我可以在编辑)。这表明存在堆栈溢出;大概是由于在堆栈上分配了8 * 8 * 8 * 4000 * 8(每个字节的字节数)= 16384000字节。

当我注释掉bar字段时,valgrind非常开心。为了使甚至陌生,使用'-O'编译gfortran-4.6.3也会导致问题消失(但不在gfortran-4.4.6下)。

要么我偶然发现了一个编译器错误,或者(更可能是因为我对Fortran相当陌生),我不明白数据在哪里分配。有人能告诉我发生了什么事吗?


有问题的代码:

main.f90时:

program main 

    use problematicArray 
    implicit none  
    type (containerType),pointer :: container 
    allocate(container) 

    container%foo%arrayData = 17.0 
    write(*,*) container%foo%arrayData(7,7,7,100) 
    deallocate(container) 
    write(*,*) 'Program finished' 

end program main 

problematicArray.f90:

module problematicArray 
    implicit none 
    private 

    integer, parameter, public :: dim1 = 4000 

    type, public :: typeWith4DArray 
     real(8), dimension(8,8,8,dim1) :: arrayData 
    end type typeWith4DArray 

    type :: typeWithChars 
     character(4), dimension(:), allocatable :: charData 
    end type typeWithChars 

    type, public :: containerType 
     type(typeWith4DArray) :: foo 
     type(typeWithChars) :: bar 
    end type containerType 

end module problematicArray 

这必须是在gfortran的错误。我没有看到任何错误。它也适用于英特尔和Oracle编译器。最好向gfortran开发者汇报。我只用了2天的gfortran 4.8中继版。

该错误与堆栈/堆的差异无关。它只是在allocate声明中崩溃。它甚至不适用于stat=errmsg=集。

请注意,您可以将模块和主程序放在单个源文件中。

+1

我报告可能的问题为http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56471 – 2013-02-27 10:19:38

+0

感谢您验证此错误,保存我的理智,并提交错误报告 - 我不' t知道正确的渠道,所以这是非常感谢。现在我将解决这个问题(通过引入几个POINTERs)。 – yatima2975 2013-03-03 15:16:51