I do have a main program with a subroutine, which needs to be called many times. The main program looks like:
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
The subroutine does all the work and I do not want to save the values of the arrays. They are mostly used to store intermediate results.
The subroutine looks like:
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
I found that I have problems with two of the 20 arrays. If I double the dimension开发者_StackOverflow of these two arrays I can run the program without problems for two times. The program stops with the error message "Program exception Array bound exceeded"
If I take dimension*10, then I can run the program 10 times and get the same error.
But if I take dimension*100, I can run the program only around 30 times and get the error "Program exception - stack overflow"
I do not know where the problem might lie, since I treated all arrays in the same way and only two arrays have this problem. Thank you !
The issue is hard to diagnose without the actual code. Does the subroutine know anything about the loop and counter in the main program or the number of times you're calling the subroutine? I'm guessing for these two special arrays, you are accessing an element by an index calculated using i, the counter in the main loop.
What compiler are you using? For gfortran, there's a flag to test if arrays are out of bounds, ie read the answer to this question. For other compilers, there are likely similar flags. You can compile using these flags, and hopefully you'll get more info about where the array out of bounds issue is occurring, e.g. your compiler calls this
"Program exception Array bound exceeded"
but gives no info about the line of code causing the issue.
Here's a program doing what I think you're doing:
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
If I compile this, like so:
gfortran -fbounds-check test2.f90
I get the following output:
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)
It's not clear why your getting a stack overflow, but I'm guessing you finally hit a point where your arrays just take up too much memory to start. If you provide more info, I might be able to help more. What does your code actually look like?
The real problem is probably the "array bounds exceeded" error -- this is an indication of a bug, i.e., a coding mistake that is causing the program to try to access an array element outside of the array. Illegal memory access can cause other bugs. Increasing the array sizes larger than you think that they need to be (if that is what you are doing) is a poor patch to the real problem. I suggest solving the array bounds bug before proceeding further. Why is the index either <1 or larger than the size of the array? See the answer of @Yann.
In the second part do you mean that you are increasing the dimensions by factors of 10 and 100? Some operating systems have surprisingly small default stack sizes. If there really is a stack overflow problem, there are three solutions to choose from: 1) redesign your program to use smaller arrays, 2) increase the stack size, or 3) move the arrays from the stack to the heap. Method 2 depends on your OS. Most compilers provide compile options to move either all arrays or large arrays from the stack, e.g., see forrt1: severe (170): Program Exception - stack overflow
Also, with twenty arrays array_1 (len) to array_20 (len) the code might be cleaner with a single array (len, 20).
精彩评论