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

时间:2013-02-27 09:05:10

标签: memory-management fortran gfortran

我不明白为什么如果bar中存在containerType字段,以下程序会使用SIGSEGV进行段错误,如果被注释掉,则无效。我在x86_64上,用gfortran-4.4.6和gfortran-4.6.3编译。

据我所知,使用指向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

1 个答案:

答案 0 :(得分:2)

这一定是gfortran中的一个错误。我没有看到任何错误。它也适用于Intel和Oracle编译器。最好向gfortran开发者报告。我只用2天的gfortran 4.8主干构建了它。

错误与堆栈/堆差异无关。它只是在allocate语句中崩溃。它甚至不适用于stat=errmsg=设置。

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