【发布时间】:2021-02-22 21:30:39
【问题描述】:
我正在比较两个文件并使用 Fortran 查找并置点。代码在我的带有 gfortran 版本 10.2.0 的笔记本电脑上运行良好,而我将此代码保存在我的 ssh 服务器上(ssh 使用 gfortran 4.8.5;也尝试使用版本 8.3.1),它适用于大多数迭代,但提供几次迭代出现以下错误:
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7F750B7F8697
#1 0x7F750B7F8CDE
#2 0x7F750ACF33FF
#3 0x402493 in MAIN__ at 1_myd_trmm_coloc.f90:?
1a_myd_trmm_coloc.sh: line 10: 42668 Segmentation fault (core dumped) ./1_myd_trmm_coloc.out < infile
以下是我的 Fortran 代码:
IMPLICIT NONE
Character*180::mydf,trmmf,outf
integer::my,mmn,md,mh,mmi,ms,mat
real::mla,mlo,ma412,ma470,ma550,ma660,mae
integer::ty,tmn,td,th,ic,i,j,i1,j1,i22,j22,n
real::tla,tlo,tpr
real,allocatable::m(:,:),t(:,:)
real::delat,delon,c,a,dist,rlon1,rlon2,rlat1,rlat2
real::mtim,ttim,maxttim,minttim,minlat,maxlat,minlon,maxlon
real,dimension(100000)::ds,ala,alo
integer,dimension(100000)::ay,amn,ad,ah,ami,as,aat
real,dimension(100000)::a412,a470,a550,a660,aae,ppr
read*,mydf
read*,trmmf
read*,outf
open(11,file=mydf,status='old')
i=0
5 read(11,*,end=90,err=80)my,mmn,md,mh,mmi,ms,mla,mlo, &
ma412,ma470,ma550,ma660,mae,mat
i=i+1
80 goto 5
90 close(11)
allocate(m(i,14))
open(11,file=mydf,status='old')
i1=0
6 read(11,*,end=91,err=81)my,mmn,md,mh,mmi,ms,mla,mlo, &
ma412,ma470,ma550,ma660,mae,mat
i1=i1+1
m(i1,1)=my ; m(i1,2)=mmn ; m(i1,3)=md
m(i1,4)=mh ; m(i1,5)=mmi ; m(i1,6)=ms
m(i1,7)=mla ; m(i1,8)=mlo ; m(i1,9)=ma412
m(i1,10)=ma470 ; m(i1,11)=ma550 ; m(i1,12)=ma660
m(i1,13)=mae ; m(i1,14)=mat
81 goto 6
91 close(11)
open(12,file=trmmf,status='old')
j=0
15 read(12,*,end=190,err=180)ty,tmn,td,th,tla,tlo,tpr
j=j+1
180 go to 15
190 close(12)
allocate(t(j,7))
open(12,file=trmmf,status='old')
j1=0
16 read(12,*,end=191,err=181)ty,tmn,td,th,tla,tlo,tpr
j1=j1+1
t(j1,1)=ty ; t(j1,2)=tmn ; t(j1,3)=td
t(j1,4)=th ; t(j1,5)=tla ; t(j1,6)=tlo
t(j1,7)=tpr ;
181 go to 16
191 close(12)
open(51,file=outf,status='unknown')
do i22=1,i
n=0; ds=-999.0
ala=-999.0;alo=-999.0;a412=-999.0;a470=-999.0
a550=-999.0;a660=-999.0;aae=-999.0;aat=-999;
ppr=-999.0;
ic=0
do j22=1,j
if(t(j22,1).eq.m(i22,1).and.t(j22,2).eq.m(i22,2).and. &
t(j22,3).eq.m(i22,3)) then
minlat=t(j22,5)-0.125; maxlat=t(j22,5)+0.125
minlon=t(j22,6)-0.125; maxlon=t(j22,6)+0.125
mtim=m(j22,4)+(m(j22,5)/60)+(m(j22,6)/3600)
ttim=t(j22,4)
minttim=ttim-0.5; maxttim=ttim+0.5
if(m(i22,7).ge.minlat.and.m(i22,7).le.maxlat.and. &
m(i22,8).ge.minlon.and.m(i22,8).le.maxlon.and. &
mtim.ge.minttim.and.mtim.le.maxttim) then
rlat1=(m(i22,7)*3.141592657)/180.0; rlat2=(t(j22,5)*3.141592657)/180.0
rlon1=(m(i22,8)*3.141592657)/180.0; rlon2=(t(j22,6)*3.141592657)/180.0
delat=rlat2-rlat1; delon=rlon2-rlon1
a=SIN(delat/2.0)**2+(COS(rlat1)*COS(rlat2)*SIN(delon/2.0)**2)
c=2.0*atan2(sqrt(a),sqrt(1-a))
dist=6378136.300*c
ic=ic+1
! print*,ic
ds(ic)=dist
ala(ic)=m(i22,7)
alo(ic)=m(i22,8)
ay(ic)=m(i22,1); amn(ic)=m(i22,2); ad(ic)=m(i22,3)
ah(ic)=m(i22,4); ami(ic)=m(i22,5); as(ic)=m(i22,6)
a412(ic)=m(i22,9); a470(ic)=m(i22,10)
a550(ic)=m(i22,11); a660(ic)=m(i22,12)
aae(ic)=m(i22,13); aat(ic)=m(i22,14)
! py(ic)=t(j22,1); pmn(ic)=t(j22,2); pd(ic)=t(j22,3)
! ph(ic)=t(j22,4); pla(ic)=t(j22,5); plo(ic)=t(j22,6)
ppr(ic)=t(j22,7)
end if
end if
end do
if (ic>0)then
write(51,111)minval(ds,ds.ne.-999.0), ay(minloc(ds,ds.ne.-999.0)), &
amn(minloc(ds,ds.ne.-999.0)), ad(minloc(ds,ds.ne.-999.0)), &
ah(minloc(ds,ds.ne.-999.0)), ami(minloc(ds,ds.ne.-999.0)), &
as(minloc(ds,ds.ne.-999.0)), ala(minloc(ds,ds.ne.-999.0)), &
alo(minloc(ds,ds.ne.-999.0)), a412(minloc(ds,ds.ne.-999.0)), &
a470(minloc(ds,ds.ne.-999.0)), a550(minloc(ds,ds.ne.-999.0)), &
a660(minloc(ds,ds.ne.-999.0)), aae(minloc(ds,ds.ne.-999.0)), &
aat(minloc(ds,ds.ne.-999)), ppr(minloc(ds,ds.ne.-999.0))
n=n+1
! print*,n
end if
end do
111 format(f16.6,1x,i4,1x,5(1x,i2.2),1x,2(1x,f8.3),1x,5(1x,f6.3),1x,i2,1x,f8.3)
deallocate(m)
deallocate(t)
close(51)
end
我正在寻找代码中的错误。 以下是示例数据文件:
文件-1
2008 04 06 09 27 03 10.250 50.250 0.303 0.303 0.303 0.303 0.000 1
2008 04 06 09 27 03 10.500 50.500 0.247 0.247 0.247 0.247 0.000 1
2008 04 06 09 27 03 10.750 50.500 0.219 0.180 0.142 0.111 1.500 2
2008 04 06 09 27 03 11.000 50.500 0.157 0.129 0.102 0.079 1.500 2
2008 04 06 09 27 46 11.250 50.000 0.064 0.053 0.042 0.032 1.500 2
2008 04 06 09 27 46 11.250 50.250 0.151 0.124 0.098 0.076 1.500 2
2008 04 06 09 27 46 11.500 50.250 0.129 0.106 0.083 0.065 1.500 2
文件-2
2008 4 6 6 9.875 29.125 0
2008 4 6 6 10.125 29.125 0
2008 4 6 6 10.375 29.125 0
2008 4 6 6 10.625 29.125 0
2008 4 6 6 10.875 29.125 0
2008 4 6 6 11.125 29.125 0
2008 4 6 6 11.375 29.125 0
2008 4 6 6 11.625 29.125 0
2008 4 6 6 11.875 29.125 0
2008 4 6 6 12.125 29.125 0
【问题讨论】:
-
对于所有 Fortran 问题,请使用标签 fortran。使用 gfortran 时,使用标志
-g -Wall -fcheck=all编译代码以获得更有用的回溯并检查某些编码错误。我在您的代码中看不到任何IMPLICIT NONE。将它用于您的所有代码,并在每次要求其他人检查您的代码时使用它。这非常重要。 -
感谢您的回复。我做了
-g -Wall -fcheck=all来获取回溯,但它没有任何警告。正如我所说,代码非常适合高于 5.x 的 gfortran 版本,但它只会在 gfortran 4.8 版本的几次迭代中产生问题。我忘记在此处添加IMPLICIT NONE。谢谢你的指出。 -
所以,不要使用早于 5.x 的版本!对编译器进行了数千次更改和修复。或者,用你的头撞你的桌子。
-
如果 gfortran-10.2 可用,我认为尝试“-Wall -Wextra”选项可能很有用(这给了我很多警告,如实数与实数比较、实数与整数赋值)用于堆栈等的大型数组等)
-
重点是你应该在这里发布更好的回溯。请edit您的问题并插入。但是,我同意您应该使用更新的 GCC 版本。请注意,您始终可以在主目录中安装自己的 gcc。