2011-08-05 57 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)。