Fortran 子程序分段错误
我正试图在我的程序中对u和up2进行Ah=b分解。然而,up2的第一个值取决于u。为了不重复分解解析,我把它做成了一个子例程,但每当我试图在u和up2的同一个循环中调用它时,我总是会得到无法识别的信号错误。请了解编译器警告和运行时错误检查。在程序上使用带有适当标志的gfortran,我得到:Fortran 子程序分段错误,fortran,fortran90,fortran95,Fortran,Fortran90,Fortran95,我正试图在我的程序中对u和up2进行Ah=b分解。然而,up2的第一个值取决于u。为了不重复分解解析,我把它做成了一个子例程,但每当我试图在u和up2的同一个循环中调用它时,我总是会得到无法识别的信号错误。请了解编译器警告和运行时错误检查。在程序上使用带有适当标志的gfortran,我得到: PROGRAM olaf IMPLICIT NONE INTEGER :: i, j, nc, nd,ok,iter REAL
PROGRAM olaf
IMPLICIT NONE
INTEGER :: i, j, nc, nd,ok,iter
REAL :: alph, bet, chi, ninf1, C1, ninf2, C2
REAL, DIMENSION(:), ALLOCATABLE :: u,up2
REAL :: E, k, Lc, hc, eps, h, Ld, Cai
INTEGER, DIMENSION(7) :: valnc = (/ 10, 50, 100, 500, 1000, 5000, 10000/)
Do iter=1,7
nc = valnc(iter)
Ld=0.2*Lc ; nd=((Lc+Ld)/h)-nc;
E=25. ; k=125. ; hc=0.01 ; eps=0.01 ; Lc=1 ;
h = Lc/nc ; chi=sqrt((E*hc)/k) ; alph= -(1/h**2) ; bet=(2/h**2)+(k/(E*hc)) ;
CALL resolution(0,nc,bet,2*alph,alph,2*alph,-2*eps/h,2*eps/h,u)
Cai=u(nc)
CALL resolution(nc+1,(nc+nd)+1,-2.0,2.0,1.0,2.0,2.0*eps*h,-2*eps*h,up2,Cai)
DEALLOCATE(u,up2)
END DO
CONTAINS
SUBROUTINE resolution (n1,n2,a,b1,b,b2,c1,c2,u1,u2)
INTEGER, INTENT(IN) :: n1,n2
REAL, INTENT(IN):: a,b1,b,b2,c1,c2
REAL, INTENT(IN),OPTIONAL :: u2
REAL, DIMENSION (:),ALLOCATABLE, INTENT(OUT) :: u1
REAL, DIMENSION(:), ALLOCATABLE :: Ap, Ae, Aw, bh, Lw, Lp, Ue, y
INTEGER :: i
Logical :: Exist
ALLOCATE(Ap(n1+1:n2), Ae(n1:n2), Aw(n1:n2),bh(n1:n2))
ALLOCATE(Lw(n1:n2), Lp(n1:n2), Ue(n1:n2), y(n1:n2),u1(n1:n2))
Aw=0; Ap=0; Ae=0; bh= 0 ; Lw = 0 ; Lp = 0 ; Ue = 0 ; y=0; Lc=0;
Exist=Present(u2)
IF(Exist .eqv. .true.)THEN
u1(n1)=u2
END IF
DO i = n1,n2
Ae(i) = b
Ap(i) = a
Aw(i) = b
END DO
Ae(n1)=b1
Aw(n2)=b2
bh(n1)=c1
bh(n2)=c2
Lp(n1) = Ap(n1+2)
Ue(n1) = Ae(n1)/Lp(n1)
DO i = n1+1, n2-1
Lw(i) = Aw(i)
Lp(i) = Ap(i) - Lw(i)*Ue(i-1)
Ue(i) = Ae(i)/Lp(i)
END DO
Lw(n2) = Aw(n2)
Lp(n2) = Ap(n2) - Lw(n2)*Ue(n2-1)
y(n1) = bh(n1)/Lp(n1)
DO i = n1, n2
y(i) = (bh(i) - Lw(i)*y(i-1)) / Lp(i)
END DO
u1(n2) = y(n2)
DO i = n2-1, n1, -1
u1(i) = y(i) - Ue(i)*u1(i+1)
END DO
DEALLOCATE(Ap, Ae, Aw,bh,Lw, Lp, Ue, y)
END SUBROUTINE
END PROGRAM olaf
注意两件事
您正在使用未初始化的h。编译器在第二个到最后一个警告中告诉您这一点。我不知道如何解决这个问题,你需要这样做。
您正在访问超出边界的阵列ap。这发生在生产线上
ijb@ianbushdesktop ~/work/stack $ gfortran -std=f2003 -Wall -Wextra -fcheck=all -g -O olaf.f90
olaf.f90:13:16:
Ld=0.2*Lc ; nd=((Lc+Ld)/h)-nc;
1
Warning: Possible change of value in conversion from REAL(4) to INTEGER(4) at (1) [-Wconversion]
olaf.f90:4:69:
REAL :: alph, bet, chi, ninf1, C1, ninf2, C2
1
Warning: Unused variable ‘c1’ declared at (1) [-Wunused-variable]
olaf.f90:4:80:
REAL :: alph, bet, chi, ninf1, C1, ninf2, C2
1
Warning: Unused variable ‘c2’ declared at (1) [-Wunused-variable]
olaf.f90:3:45:
INTEGER :: i, j, nc, nd,ok,iter
1
Warning: Unused variable ‘i’ declared at (1) [-Wunused-variable]
olaf.f90:3:48:
INTEGER :: i, j, nc, nd,ok,iter
1
Warning: Unused variable ‘j’ declared at (1) [-Wunused-variable]
olaf.f90:4:65:
REAL :: alph, bet, chi, ninf1, C1, ninf2, C2
1
Warning: Unused variable ‘ninf1’ declared at (1) [-Wunused-variable]
olaf.f90:4:76:
REAL :: alph, bet, chi, ninf1, C1, ninf2, C2
1
Warning: Unused variable ‘ninf2’ declared at (1) [-Wunused-variable]
olaf.f90:3:59:
INTEGER :: i, j, nc, nd,ok,iter
1
Warning: Unused variable ‘ok’ declared at (1) [-Wunused-variable]
olaf.f90:13:0:
Ld=0.2*Lc ; nd=((Lc+Ld)/h)-nc;
Warning: ‘h’ may be used uninitialized in this function [-Wmaybe-uninitialized]
olaf.f90:6:0:
REAL :: E, k, Lc, hc, eps, h, Ld, Cai
note: ‘h’ was declared here
ijb@ianbushdesktop ~/work/stack $ ./a.out
At line 51 of file olaf.f90
Fortran runtime error: Index '0' of dimension 1 of array 'ap' below lower bound of 1
Error termination. Backtrace:
#0 0x400f8d in resolution
at /home/ijb/work/stack/olaf.f90:51
#1 0x401991 in olaf
at /home/ijb/work/stack/olaf.f90:20
#2 0x401991 in main
at /home/ijb/work/stack/olaf.f90:11
ijb@ianbushdesktop ~/work/stack $
Api=a
问题是我是零。看一下代码,我从n1到n2,所以最终的问题是在这行
ijb@ianbushdesktop ~/work/stack $ gfortran -std=f2003 -Wall -Wextra -fcheck=all -g -O olaf.f90
olaf.f90:13:16:
Ld=0.2*Lc ; nd=((Lc+Ld)/h)-nc;
1
Warning: Possible change of value in conversion from REAL(4) to INTEGER(4) at (1) [-Wconversion]
olaf.f90:4:69:
REAL :: alph, bet, chi, ninf1, C1, ninf2, C2
1
Warning: Unused variable ‘c1’ declared at (1) [-Wunused-variable]
olaf.f90:4:80:
REAL :: alph, bet, chi, ninf1, C1, ninf2, C2
1
Warning: Unused variable ‘c2’ declared at (1) [-Wunused-variable]
olaf.f90:3:45:
INTEGER :: i, j, nc, nd,ok,iter
1
Warning: Unused variable ‘i’ declared at (1) [-Wunused-variable]
olaf.f90:3:48:
INTEGER :: i, j, nc, nd,ok,iter
1
Warning: Unused variable ‘j’ declared at (1) [-Wunused-variable]
olaf.f90:4:65:
REAL :: alph, bet, chi, ninf1, C1, ninf2, C2
1
Warning: Unused variable ‘ninf1’ declared at (1) [-Wunused-variable]
olaf.f90:4:76:
REAL :: alph, bet, chi, ninf1, C1, ninf2, C2
1
Warning: Unused variable ‘ninf2’ declared at (1) [-Wunused-variable]
olaf.f90:3:59:
INTEGER :: i, j, nc, nd,ok,iter
1
Warning: Unused variable ‘ok’ declared at (1) [-Wunused-variable]
olaf.f90:13:0:
Ld=0.2*Lc ; nd=((Lc+Ld)/h)-nc;
Warning: ‘h’ may be used uninitialized in this function [-Wmaybe-uninitialized]
olaf.f90:6:0:
REAL :: E, k, Lc, hc, eps, h, Ld, Cai
note: ‘h’ was declared here
ijb@ianbushdesktop ~/work/stack $ ./a.out
At line 51 of file olaf.f90
Fortran runtime error: Index '0' of dimension 1 of array 'ap' below lower bound of 1
Error termination. Backtrace:
#0 0x400f8d in resolution
at /home/ijb/work/stack/olaf.f90:51
#1 0x401991 in olaf
at /home/ijb/work/stack/olaf.f90:20
#2 0x401991 in main
at /home/ijb/work/stack/olaf.f90:11
ijb@ianbushdesktop ~/work/stack $
您正在将值0传递给n1,但将数组ap分配为
CALL resolution(0,nc,bet,2*alph,alph,2*alph,-2*eps/h,2*eps/h,u)
这与Ap的上述用法不一致。我的完全猜测是do循环应该是
ALLOCATE(Ap(n1+1:n2), Ae(n1:n2), Aw(n1:n2),bh(n1:n2))
但这是一个猜测-出现的问题是由于此循环中的越界错误。请先在启用边界检查的情况下编译。我可以看到至少有一个位置试图访问元素yn1-1。您还应该尝试获取一个跟踪,它应该告诉您发生错误的行。对于gfortran-g-fbacktrace,而对于ifort-g-traceback,应该可以做到这一点。检查文档中是否有其他编译器。此外,Lc是未初始化的,并且在调用中传递了一个变量Cairo而不是Cai。仔细检查你的代码是否是你测试过的。我没有复制我的完整程序,我只复制了困扰我的部分。我纠正了下面引用的复制错误@当我第一次单独调用子例程时,它工作得很好!但是当我在这里同时做这两件事的时候,我得到了分割错误。我尝试了很多东西,但到目前为止都没有成功。而且-g-fbacktrace没有给我任何信息。@HighPerformanceMark这是我角色的复制错误。很抱歉,用gfortran-Og-g-fbacktrace-Wall-Wextra-fcheck=all olaf.f90比较您当前的代码,可以得到一个非常有用的回溯:在文件olaf.f90 Fortran的第51行,运行时错误:数组“ap”的维度1的索引“0”低于1的下限。请注意,在子例程解析中,Ap被分配为具有索引n1+1:n2,当您第一次调用子例程时,n1=0,因此访问i=n1=0的Api是一种越界数组访问。