首页 > 解决方案 > 第二次用户输入后的分段错误

问题描述

我这样编译:

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 以为第二个输入创建新空间,但我遇到了与名称相同时相同的问题。我尝试过的一切都停在“第 2a 点”。此外,如果我切换模块调用的顺序,问题仍然存在于第二个文件中。在更多尝试 gfortran -c -g -fbacktrace -fcheck=all 之后,我得到的错误是:

PS:一些没有正确缩进的命令只是这样写,用于格式化目的。

  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

标签: fortran

解决方案


我有一点猜测,假设代码是正确的。您可以使用该行调用 C 预处理器

#include "rvarrays.inc"

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

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

包含不起作用,并且未定义数组。但是既然你没有implicit none名字,那些数组的名字仍然是有效的,但是对于一个标量。尝试添加标志,或删除 Fortran 包含的 #。

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


推荐阅读