如何修复Fortran程序中的“分段错误”

时间:2019-04-26 09:21:58

标签: fortran gfortran

我编写了此程序,该程序从文件中读取每日网格化气候模型数据(6个变量),并将其用于进一步的计算。在运行pgm的时间相对较短(例如5年)时,它可以正常工作,但是当我在所需的30年时间内运行pgm时,会出现“分段错误”。

系统描述:带有Windows 10专业版的Core i7 vPro的Lenovo Thinkpad 程序在Oracle VM VirtualBox内的Fedora(64位)中运行

在注释完所有内容并逐节检查后,我发现:

  1. 只要读取4个变量,一切都可以正常工作30年
  2. 添加第5或第6个变量后,问题就会逐渐蔓延
  3. 或者,我可以使用所有6个变量来运行它,但是它只能在较短的分析周期(例如22年)内运行

所以问题可能出在哪里:

  • 我从另一个pgm借来的语句:recl = AX * AY * 4,但是更改4并不能解决问题
  • 我正在运行pgm的系统

我尝试了其他地方建议的“ ulimit -s unlimited”命令,但仅收到响应“无法修改限制:不允许操作”。

文件= par_query.h

  integer AX,AY,startyr,endyr,AT
  character pperiod*9,GCM*4

  parameter(AX=162,AY=162)          ! dim of GCM array
  parameter(startyr=1961,endyr=1990,AT=endyr-startyr+1,
 &          pperiod="1961_1990")
  parameter(GCM='ukmo')

文件= query.f

  program query
  !# A FORTRAN program that reads global climate model (GCM) data to 
  !# be used in further calculations
  !# uses parameter file: par_query.h
  !# compile as: gfortran -c -mcmodel=large query.f
  !#             gfortran query.o
  !# then run: ./a.out

  ! Declarations ***************************************************
  implicit none
  include 'par_query.h'    ! parameter file
  integer :: i,j,k,m,n,nn,leapa,leapb,leapc,leapn,rec1,rec2,rec3,
 &           rec4,rec5,rec6
  integer, dimension(12) :: mdays
  real :: ydays,nyears
  real, dimension(AX,AY,31,12,AT) :: tmax_d,tmin_d,rain_d,rhmax_d,
 &                                   rhmin_d,u10_d
  character :: ipath*43,fname1*5,fname2*3,nname*14,yyear*4,mmonth*2,
 &             ext1*4

  ! Data statements and defining characters ************************
  data mdays/31,28,31,30,31,30,31,31,30,31,30,31/   ! Days in month  
  ydays=365.                                        ! Days in year
  nyears=real(AT)                ! Analysis period (in years)
  ipath="/run/media/stephan/SS_Elements/CCAM_africa/" ! Path to 
                                 ! input data directory
  fname1="ccam_"                 ! Folder where data is located #1       
  fname2="_b/"                   ! Folder where data is located #2
  nname="ccam_africa_b."         ! Input filename (generic part)
  ext1=".dat"
  leapa=0
  leapb=0
  leapc=0
  leapn=0

  ! Read daily data from GCM ***************************************
  do n=startyr,endyr    ! Start looping through years --------------
    write(yyear,'(i4.4)')n
    nn=n-startyr+1
    ! Test for leap years
    leapa=mod(n,4)
    leapb=mod(n,100)
    leapc=mod(n,400)
    if (leapa==0) then
      if (leapb==0) then
        if (leapc==0) then
          leapn=1
        else
          leapn=0
        endif
      else
        leapn=1
      endif
    else
      leapn=0
    endif
    if (leapn==1) then
      mdays(2)=29
      ydays=366.
    else
      mdays(2)=28
      ydays=365.
    endif
    do m=1,12    ! Start looping through months -------------------- 
      write(mmonth,'(i2.2)')m
      ! Reading daily data from file
      print*,"Reading data for ",n,mmonth
      open(101,file=ipath//fname1//GCM//fname2//nname//GCM//"."//
 &             yyear//mmonth//ext1,access='direct',recl=AX*AY*4)
      do k=1,mdays(m)    ! Start looping through days --------------
        rec1=(k-1)*6+1
        rec2=(k-1)*6+2
        rec3=(k-1)*6+3
        rec4=(k-1)*6+4
        rec5=(k-1)*6+5
        rec6=(k-1)*6+6
        read(101,rec=rec1)((tmax_d(i,j,k,m,nn),i=1,AX),j=1,AY)
        read(101,rec=rec2)((tmin_d(i,j,k,m,nn),i=1,AX),j=1,AY)
        read(101,rec=rec3)((rain_d(i,j,k,m,nn),i=1,AX),j=1,AY)
        read(101,rec=rec4)((rhmax_d(i,j,k,m,nn),i=1,AX),j=1,AY)
        read(101,rec=rec5)((rhmin_d(i,j,k,m,nn),i=1,AX),j=1,AY)
        read(101,rec=rec6)((u10_d(i,j,k,m,nn),i=1,AX),j=1,AY)
      enddo    ! k-loop (days) ends --------------------------------
      close(101)
    enddo    ! m-loop (months) ends --------------------------------
  enddo    ! n-loop (years) ends -----------------------------------

  end program query

0 个答案:

没有答案