Fortran错误:程序接收信号SIGSEGV:分段错误 - 无效的内存引用

时间:2015-05-27 15:44:12

标签: cygwin fortran

我尝试使用显式方法(抛物线微分方程)运行海洋温度模型25年。

如果我运行一年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。

我不确定这个问题是由错误的编译器还是其他原因造成的。

有人对此有任何想法吗?这对我有很大的帮助!

此致

1 个答案:

答案 0 :(得分: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

您的数组temp的界限为0:101,您从n循环1101,您可以在n=101访问temp(j-1,102) temp 1}},这是超出界限的。

这意味着你写的是a之外的任何内存,虽然这会使你的程序总是不正确,但它有时会导致崩溃,这取决于其他各种事情。增加k会触发这一点,因为数组的列主要排序意味着a连续变化并且a跨越,而temp会增加您对第二维的界限访问进一步在内存中超越temp(:,101) = temp(:,100)更改被无效访问覆盖的内容。

在循环之后设置temp(:,101)意味着无需在上面的循环中计算do n = 1,k ,因此您可以从

更改其循环边界
do n = 1, k-1

temp

将修复1.4.x上的越界访问。