第二次用户输入后出现细分错误

时间:2019-04-11 09:08:52

标签: fortran

我这样编译:

f77 -c readheader.F
f77 -c readheader2.F
make (for the main program, which is necessary to have a makefile for)

并运行:

./decpar

输出:

Which datafile?
Point 2a

Program received signal SIGSEGV: Segmentation fault - invalid memory
reference.

Backtrace for this error:
#0  0x7FF5E4A62E08
#1  0x7FF5E4A61F90
#2  0x7FF5E41934AF
#3  0x7FF5E4B25C40
#4  0x7FF5E4B26197
#5  0x7FF5E4B34B87
#6  0x4056B8 in __mysubs2_MOD_readheader2
#7  0x401CA5 in MAIN__ at decpar.F:29 (discriminator 88)
Segmentation fault (core dumped)

我不会发布整个代码,因为它庞大且不必要。幸运的是,该错误出现在前几行中。我有两个模块,在这两个模块中,都要求用户键入数据文件的名称,以便提取信息并将其定向到主程序。我试图刷新(5)数据文件,以防万一出于某些奇怪的原因它没有被第二个用户输入覆盖,并且出现“段错误-无效的内存引用”。我试图将数据文件的名称更改为datafile2以便为第二个输入创建新的空间,但是当名称相同时,我遇到了同样的问题。我尝试过的一切都停留在“ Point 2a”上。另外,如果我切换模块调用的顺序,问题仍然存在于第二个文件中。经过更多尝试gfortran -c -g -fbacktrace -fcheck = all之后,我得到的错误是: Fortran运行时错误:数组'thetax'的维度1的索引'1'高于0的上限。

P.S .:某些未正确缩进的命令就是这样写的,出于格式化目的。

  module MySubs
  contains

  subroutine readheader(theta,thetax,thetay,thetaz)

  include 'psize.inc'
  include 'pinfo.inc'
  #include "rvarrays.inc"
  include 'itype.inc'
  include 'iodefs.inc'

  REAL,ALLOCATABLE, intent(inout), DIMENSION (:) :: thetay, thetaz
  REAL,ALLOCATABLE, intent(inout), DIMENSION (:) :: theta, thetax

  ALLOCATE (theta(nobj),thetax(nobj),thetay(nobj),thetaz(nobj))

  1    print*,'Which datafile?'
  read(*,'(a)') datafile 

  CALL readdata

  do i=1,nobj
    if (i.LT.nobj) then
        thetax(i)=(v(1,i+1)-v(1,i))*(r(1,i+1)-r(1,i))**(-1)
        thetay(i)=(v(2,i+1)-v(2,i))*(r(2,i+1)-r(2,i))**(-1)
        thetaz(i)=(v(3,i+1)-v(3,i))*(r(3,i+1)-r(3,i))**(-1)
        theta(i)=thetax(i)+thetay(i)+thetaz(i)
        else 
        thetax(i)=(v(1,i)-v(1,i-1))*(r(1,i)-r(1,i-1))**(-1)
        thetay(i)=(v(2,i)-v(2,i-1))*(r(2,i)-r(2,i-1))**(-1)
        thetaz(i)=(v(3,i)-v(3,i-1))*(r(3,i)-r(3,i-1))**(-1)
        theta(i)=thetax(i)+thetay(i)+thetaz(i)
    endif 
  end do
  RETURN
  end subroutine readheader

  end module MySubs

  module MySubs2
  contains

  subroutine readheader2(thetapx, thetapy, thetapz,thetap)

  include 'psize.inc'
  include 'pinfo.inc'
  #include "rvarrays.inc"
  include 'itype.inc'
  include 'iodefs.inc'

  character*1 answer
  REAL :: z2
  REAL,ALLOCATABLE,intent(inout),DIMENSION (:) :: thetapz,thetap
  REAL,ALLOCATABLE,intent(inout),DIMENSION (:) :: thetapx, thetapy
  ALLOCATE (thetapx(nobj),thetapy(nobj),thetapz(nobj))


  1    print*,'Which datafile?'
  print*, 'Point 2a'
  read(*,'(a)') datafile
  print*, 'Point 2b'
  CALL readdata

 do i=1,nobj

  if (i<nobj) then
    thetapx(i)=(v(1,i+1)-v(1,i))*(r(1,i+1)-r(1,i))**(-1)
    thetapy(i)=(v(2,i+1)-v(2,i))*(r(2,i+1)-r(2,i))**(-1)
        thetapz(i)=(v(3,i+1)-v(3,i))*(r(3,i+1)-r(3,i))**(-1)
        thetap(i)=thetapx(i)+thetapy(i)+thetapz(i)
  else 
    thetapx(i)=(v(1,i)-v(1,i-1))*(r(1,i)-r(1,i-1))**(-1)
    thetapy(i)=(v(2,i)-v(2,i-1))*(r(2,i)-r(2,i-1))**(-1)
        thetapz(i)=(v(3,i)-v(3,i-1))*(r(3,i)-r(3,i-1))**(-1)
        thetap(i)=thetapx(i)+thetapy(i)+thetapz(i)
  endif 

 end do

  RETURN
  end subroutine readheader2

  end module MySubs2

  PROGRAM decpar

  use MySubs
  use MySubs2

  include 'psize.inc'
  include 'pinfo.inc'
  #include "rvarrays.inc"
  include 'itype.inc'
  include 'iodefs.inc'

  REAL,ALLOCATABLE,DIMENSION(:) :: dztheta,dthetax,dthetay,dthetaz
  REAL,ALLOCATABLE,DIMENSION(:) :: convtheta,dttheta,q1,q2,q3,q
  REAL,ALLOCATABLE,DIMENSION(:) :: theta,thetax,thetay,thetaz
  REAL,ALLOCATABLE,DIMENSION(:) :: thetapx, thetapy, thetapz,thetap
  REAL,ALLOCATABLE,DIMENSION(:) :: dthetasp

  ALLOCATE(dztheta(nobj),dthetax(nobj),dthetay(nobj),dthetaz(nobj))
  ALLOCATE(q(nobj),dthetasp(nobj),q3(nobj))
  ALLOCATE(convtheta(nobj),dttheta(nobj),q1(nobj),q2(nobj))

  CALL readheader(theta,thetax,thetay,thetaz)
  CALL readheader2(thetapx, thetapy, thetapz,thetap)

  q0=-0.55
  do i=1,nobj
    dztheta(i)=(thetap(i)-theta(i))*(z1-z2)**(-1)
    dttheta(i)=-(2./3.)*dztheta(i)
    if (i<nobj) then
       dthetax(i)=r(1,i)*(thetax(i+1)-thetax(i))/(r(1,i+1)-r(1,i))
       dthetay(i)=r(2,i)*(thetay(i+1)-thetay(i))/(r(2,i+1)-r(2,i))
       dthetaz(i)=r(3,i)*(thetaz(i+1)-thetaz(i))/(r(3,i+1)-r(3,i))
       dthetasp(i)=dthetax(i)+dthetay(i)+dthetaz(i)
    else 
       dthetax(i)=r(1,i)*(thetax(i)-thetax(i-1))/(r(1,i)-r(1,i-1))
       dthetay(i)=r(2,i)*(thetay(i)-thetay(i-1))/(r(2,i)-r(2,i-1))
       dthetaz(i)=r(3,i)*(thetaz(i)-thetaz(i-1))/(r(3,i)-r(3,i-1))
       dthetasp(i)=dthetax(i)+dthetay(i)+dthetaz(i)
    endif
  convtheta(i)=dttheta(i)+h100*100.0*dthetasp(i)  
  q1(i)=-1+(1+q0)*(1+theta(i)/(3.0*100.0*h100))**(-2)
  q2(i)=-(dttheta(i)/(3*100*h100)**2)
  q3(i)=(1+theta(i)/(3*100*h100))**(-2)
  q(i)=q1(i)+q2(i)*q3(i)
  end do

  DEALLOCATE(dztheta,dthetax,dthetay,dthetaz)
  DEALLOCATE(q,q1,q2,q3,dthetasp)
  DEALLOCATE(convtheta,dttheta)

  end

2 个答案:

答案 0 :(得分:0)

假设代码正确,我有点猜测。您可以通过以下行调用C预处理程序

#include "rvarrays.inc"

可能在那里定义了一些数组。没有-cpp标记

f77 -c readheader.F
f77 -c readheader2.F

包含不起作用,并且未定义数组。但是由于您没有implicit none,所以这些数组的名称仍然是有效名称,只是标量。尝试添加标志,或删除Fortran包含的#号。

另一方面,您应该从#中获得编译错误,而没有-cpp标志...

答案 1 :(得分:0)

幸运的是,我自己发现了问题,因为实际上您不可能安装代码(因为这是必需的,即使我上传了所有文件,我也无法确保那是别人的属性)。我的数组似乎已分配,但没有分配。程序当时不知道'nobj'的值。因此,将所有ALLOCATE语句放在CALL之后,即可解决问题!