Fortran error: Program received signal SIGSEGV: Segmentation fault - invalid memory reference
Fortran error: Program received signal SIGSEGV: Segmentation fault - invalid memory reference
我正在尝试 运行 使用显式方法(抛物线微分方程)建立一个 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。
我不确定这个问题是由于错误的编译器还是其他原因造成的。
有人对此有什么想法吗?这对我有很大帮助!
此致
查看代码中的以下几行:
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
从 1
到 101
在迭代 n=101
你访问temp(j-1,102)
,这是越界的。
这意味着您正在写入超出 temp
的任何内存,虽然这会使您的程序始终不正确,但它有时只会导致崩溃,这取决于其他各种因素。增加 a
会触发此事件,因为数组的列主要排序意味着 k
连续变化并被 a
跨越,并且随着 a
增加您对第二维的越界访问在 temp
之外的内存中更远,改变了被您的无效访问覆盖的内容。
在你的循环之后你设置了temp(:,101) = temp(:,100)
意味着在上面的循环中不需要计算temp(:,101)
,所以你可以改变它的循环边界从
do n = 1,k
至
do n = 1, k-1
这将修复 temp
.
上的越界访问
我正在尝试 运行 使用显式方法(抛物线微分方程)建立一个 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。
我不确定这个问题是由于错误的编译器还是其他原因造成的。
有人对此有什么想法吗?这对我有很大帮助!
此致
查看代码中的以下几行:
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
从 1
到 101
在迭代 n=101
你访问temp(j-1,102)
,这是越界的。
这意味着您正在写入超出 temp
的任何内存,虽然这会使您的程序始终不正确,但它有时只会导致崩溃,这取决于其他各种因素。增加 a
会触发此事件,因为数组的列主要排序意味着 k
连续变化并被 a
跨越,并且随着 a
增加您对第二维的越界访问在 temp
之外的内存中更远,改变了被您的无效访问覆盖的内容。
在你的循环之后你设置了temp(:,101) = temp(:,100)
意味着在上面的循环中不需要计算temp(:,101)
,所以你可以改变它的循环边界从
do n = 1,k
至
do n = 1, k-1
这将修复 temp
.