2015-05-27 32 views
-1

我嘗試使用顯式方法(拋物型微分方程)運行25年的海洋溫度模型。Fortran錯誤:程序接收到的信號SIGSEGV:分段錯誤 - 無效內存引用

如果我運行一年a = 3600或五年a = 18000它工作正常。

但是,當我運行它25年a = 90000它崩潰。

a是使用的時間步數。一年被認爲是360天。時間步驟是4320秒,delta_t = 4320.

這裏是我的代碼:

program task 
!declare the variables 
implicit none 
! initial conditions 
real,parameter :: initial_temp = 4. 
! vertical resolution (delta_z) [m], vertical diffusion coefficient (av) [m^2/s], time step delta_t [s] 
real,parameter :: delta_z = 2., av = 2.0E-04, delta_t = 4320. 
! gamma 
real,parameter :: y = (av * delta_t)/(delta_z**2) 
! horizontal resolution (time) total points 
integer,parameter :: a = 18000 
!declaring vertical resolution 
integer,parameter :: k = 101 
! declaring pi 
real, parameter :: pi = 4.0*atan(1.0) 
! t = time [s], temp_a = temperature at upper boundary [°C] 
real,dimension(0:a) :: t 
real,dimension(0:a) :: temp_a 
real,dimension(0:a,0:k) :: temp 
integer :: i 
integer :: n 
integer :: j 


t(0) = 0 
do i = 1,a 
    t(i) = t(i-1) + delta_t 
end do 

! temperature of upper boundary 
temp_a = 12. + 6. * sin((2. * t * pi)/31104000.) 

temp(:,0) = temp_a(:) 
temp(0,1:k) = 4. 

! Vertical resolution 
do j = 1,a 
    do n = 1,k 
    temp(j,n) = temp(j-1,n) + (y * (temp(j-1,n+1) - (2. * temp(j-1,n)) + temp(j-1,n-1))) 
    end do 
    temp(:,101) = temp(:,100) 
end do 


print *, temp(:,:) 
end program task 

變量a是第11行(integer,parameter :: a = 18000

至於說,a = 18000作品,a = 90000沒有。

90000讓我得到:

Program received signal SIGSEGV: Segmentation fault - invalid memory reference. 

Backtrace for this error: 

RUN FAILED (exit value 1, total time: 15s) 

我使用的是Windows 8.1,NetBeans和Cygwin的(已gfortran內置)一個Fortran。

我不確定這個問題是否由錯誤的編譯器或其他引起的。

有沒有人有任何想法呢?它會幫助我很多!

問候

+2

你應該用運行時數組邊界檢查來編譯你的代碼。當你這樣做時,你應該找到你的錯誤。這與「a」而不是「k」有關。 – francescalus

+1

使用gfortran測試程序時使用'-fcheck = all -Wall -g -fbacktrace'。 –

回答

0

看看從下面幾行代碼:

integer,parameter :: k = 101 
real,dimension(0:a,0:k) :: temp 
integer :: n 

    do n = 1,k 
    temp(j,n) = temp(j-1,n) + (y * (temp(j-1,n+1) - (2. * temp(j-1,n)) + temp(j-1,n-1))) 
    end do 

你的陣列temp0:101界限,你循環n1到在迭代n=101訪問temp(j-1,102)101,這是超出界限的。

這意味着您正在寫入除temp之外的任何內存,並且這會使您的程序始終不正確,但這隻會導致有時會導致崩潰,這取決於各種其他事情。增加a會觸發此操作,因爲數組的列主要排序意味着連續更改k,並且由a跨步,並且隨着a增加您的越界,第二維的訪問進一步超出temp以改變由無效訪問覆蓋的內存。

你的循環後設置temp(:,101) = temp(:,100)這意味着沒有必要在上面的循環來計算temp(:,101),這樣你就可以從

do n = 1,k 

do n = 1, k-1 

來解決這些改變其循環邊界在temp以外的區域訪問。

+0

感謝噸,這絕對解決了崩潰! 但是數字似乎是錯誤的。 我忘了指出'temp(:,101)= temp(:,100)'是底部的邊界條件。 dT/dz = 0在海底。 – Huntemerson

+0

@Huntemerson現在你的代碼運行好了,你可以調試它的邏輯並驗證你的算法是正確的。對不起,我幫不了你。 – casey

相關問題