2011-08-05 54 views
0

我有一个带有子程序的主程序,需要多次调用它。主程序如下:Fortran子程序中的Stackoverflow

program main 
open output file 
    do i = 1, 20000 
    read parameters par_1, par_2, ..., par_8 
    call subroutine (par_1, .... , par_8) 
    enddo 
end program 

该子程序完成所有工作,我不想保存数组的值。它们主要用于存储中间结果。

子程序的样子:

subroutine calcr 
    real, dimension(5000) :: array_1, array_2, .... array_20 
    read temperature into array_1 
    read pH into array_2 
    ... 
    store intermediate results into array_10 
    sotre intermediate results into array_20 
    ... 
    make final calculations 
    write the results to the output file 
    close files from which the data was read (temperature, pH...) 
end subroutine 

我发现我有问题,两个20个阵列。如果我加倍这两个数组的维数,我可以在没有问题的情况下运行两次程序。 该程序停止,并显示错误消息“程序异常数组超限”

如果我将维数* 10,那么我可以运行该程序10次,并得到相同的错误。

但如果我把维* 100,我可以运行程序只有30左右倍,得到错误“程序异常 - 堆栈溢出”

我不知道哪里出了问题可能在于,因为我对待所有数组以相同的方式,只有两个数组有这个问题。 谢谢!

+0

无法给您提供您提供的信息的答案。 –

回答

2

如果没有实际的代码,问题很难诊断。子程序是否知道主程序中的循环和计数器或调用子程序的次数?我猜这两个特殊的数组,你正在访问元素的索引计算使用i,主循环中的计数器。

你使用什么编译器?对于gfortran,有一个标志来测试数组是否超出范围,即read the answer to this question。对于其他编译器,可能会出现类似的标志。您可以使用这些标志进行编译,并希望您可以获得有关发生数组越界问题的更多信息,例如你的编译器调用这个

“的约束程序异常阵列超标”

,但给出了有关的代码导致了问题的线没有资料。

这里有一个程序在做什么,我认为你正在做的:

module global 
    integer :: nsubcalls=0 ! counter for the number of times stuff() is called 
end module 

subroutine stuff 
    use global 
    integer :: isub 
    integer :: nelements = 5000 
    real,dimension(5000) :: array_1 

    do isub=1,nelements 
    array_1(nsubcalls*nelements+isub) = isub 
    end do 

    nsubcalls = nsubcalls +1 
end subroutine 

program main 

    use global 
    integer :: i 

    nsubcalls=0 
    do i=0,20000 
    print *,"i = ",i 
    call stuff() 
    end do 

end program 

如果我编译此,像这样:

gfortran -fbounds-check test2.f90 

我得到以下输出:

i =   0 
i =   1 
At line 15 of file test2.f90 
Fortran runtime error: Array reference out of bounds for array 'array_1', upper bound of dimension 1 exceeded (5001 > 5000) 

目前尚不清楚为什么你的堆栈溢出了,但是我猜你终于达到了你的数组占用太多的地步记忆开始。如果您提供更多信息,我可能会提供更多帮助。你的代码实际上是什么样的?

2

真正的问题可能是“超出数组边界”错误 - 这是错误的指示,即导致程序尝试访问数组外的数组元素的编码错误。非法内存访问可能会导致其他错误。增加比你认为需要的更大的阵列尺寸(如果这就是你正在做的)对于真正的问题是一个很差的补丁。我建议在继续下一步之前解决数组边界问题。为什么索引是< 1或大于数组的大小?看到@Yann的回答。

在第二部分中,你的意思是说你增加10和100倍的尺寸?一些操作系统的默认堆栈大小惊人地小。如果确实存在堆栈溢出问题,可以选择三种解决方案:1)重新设计程序以使用更小的阵列,2)增加堆栈大小,或者3)将阵列从堆栈移动到堆。方法2取决于您的操作系统。大多数编译器都提供了编译选项来移动堆栈中的所有阵列或大型阵列,例如参见forrt1: severe (170): Program Exception - stack overflow

此外,使用二十个数组array_1(len)到array_20 ,20)。