Cygwin Fortran错误:程序接收信号SIGSEGV:分段错误-内存引用无效
我尝试使用显式方法(抛物线微分方程)运行一个海洋温度模型25年 如果我跑了一年Cygwin Fortran错误:程序接收信号SIGSEGV:分段错误-内存引用无效,cygwin,fortran,Cygwin,Fortran,我尝试使用显式方法(抛物线微分方程)运行一个海洋温度模型25年 如果我跑了一年a=3600或五年a=18000效果很好 然而,当我运行它25年时,它崩溃了 a是使用的时间步长量。一年被认为是360天。时间步长为4320秒,delta\u t=4320。 这是我的密码: program task !declare the variables implicit none ! initial conditions real,parameter :: initial_temp = 4. ! vertic
a=3600
或五年a=18000
效果很好
然而,当我运行它25年时,它崩溃了
a
是使用的时间步长量。一年被认为是360天。时间步长为4320秒,delta\u 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行(整数,参数::a=18000
)
如前所述,a=18000
有效,a=90000
无效
在90000时
get我得到:
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
RUN FAILED (exit value 1, total time: 15s)
我在Windows8.1、NetBeans和Cygwin(内置了gfortran)上使用fortran
我不确定这个问题是由坏的编译器还是其他原因引起的
有人对此有什么想法吗?这对我有很大帮助
关于请查看代码中的以下行:
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
的边界,你从1
循环n
到101
,在迭代中n=101
你访问temp(j-1102)
,这是超出边界的
这意味着您正在写入超出temp
范围的任何内存,虽然这会使您的程序始终不正确,但有时它只会导致崩溃,这取决于各种其他因素。增加a
会触发此操作,因为数组的列主顺序意味着k
连续变化,并以a
为步长,随着a
的增加,第二维度的越界访问在temp
之外的内存中更进一步,更改被无效访问覆盖的内容
循环后,设置temp(:,101)=temp(:,100)
意味着不需要在上述循环中计算temp(:,101)
,因此可以从
do n = 1,k
到
这将修复
temp
上的越界访问。您应该使用运行时数组边界检查来编译代码。当你这样做的时候,你应该发现你的错误。这与a
无关,但与k
有关。使用gfortran测试程序时,请使用-fcheck=all-Wall-g-fbacktrace
。非常感谢,这肯定修复了崩溃问题!然而,这些数字似乎是错误的。我忘了指出,temp(:,101)=temp(:,100)
是底部的一个边界条件。dT/dz=0在海底。@现在代码已经运行,您可以调试它的逻辑并验证您的算法是否正确。对不起,我帮不了你。
do n = 1, k-1