数组实参传递到虚参出错
大家好,我修改的程序在编译时没有报错,运行时通过print *,语句发现有一个数组传递到subroutine的虚参后发生很诡异的问题:主文件为f90,涉及错误的代码复制如下:! ... Run plume model CALL lineplu_v1(iyr,rjulday,wselev,dfelev,kms,dfLgth, & lambnot,salamb,patm, diamm, plmdim, & qscfm, frconot, & ! boundary conditions ksrc, hcell, & zamb (1:kms), & Tamb (1:kms), & DOamb(1:kms), & elevt, qwt , tplumt, comgpt, & qwd(1:ksrc), bwd(1:ksrc), ktop, oteff)
! ....Run double plume model CALL doubplu_v1(iyr,rjulday,wselev,dfelev,kms,dfLgth, & lambnot,salamb,patm, diamm, plmdim, & qscfm, frconot, & ! boundary conditions ksrc, hcell, & zamb (1:kms), & Tamb (1:kms), & DOamb(1:kms), & elevt, qwt , tplumt, comgpt, & qwd(1:ksrc), bwd(1:ksrc), kob, oteff)
其中,lineplu_v1是保存在另一个f77文件下的subroutine;我根据它为原型修改后的subroutine叫做doubplu_v1,保存在同一个f77文件下。
运行lineplu_v1时,zamb (1:kms)这个数组的传递正确,如果跳过lineplu_v1,运行doubplu_v1, zamb (1:kms)的值变得很奇怪,我在doubplu_v1的函数开头(变量声明以后位置)写了print *, locat (1:layers), (对应的虚参)结果本来应该是从-0.25到20.75之间的数字居然全都变成9.9290E-318这样大小的值。
以下是两个subroutine的声明部分:
SUBROUTINE DOUBPLU_v1(YEAR,JULDAY,WSEL,DIFFEL,LAYERS,LDIFF,LAMBNOT, +SALAMB,PATM,DIAMM,LAKE,QSCFM,FRCONOT,LAYDIFF,HCELL,LOCAT,TE,CO2M, +ELEVOB,QWOB,TPLUMEOB,COMGPOB,QWD,BWD,LAYOB,OTEFF)
C----------------------------SUBROUTINE LINEPLU_v1(YEAR,JULDAY,WSEL,DIFFEL,LAYERS,LDIFF,LAMBNOT, +SALAMB,PATM,DIAMM,LAKE,QSCFM,FRCONOT,LAYDIFF,HCELL,LOCAT,TE,CO2M, +ELEVT,QWT,TPLUMET,COMGPT,QWD,BWD,LAYTOP,OTEFF)
可能是我接触fortran时间太短,自己尝试debug了几天,摸不着头脑.....如果有好心的大神有想法的话烦请指点我一下。我现在一边向人求助一边已经打算在subroutine里手动输入 locat(1:layers)的值了......
如果您阅读到这里,非常感谢。
数组zamb没有初始化或赋值 pasuka 发表于 2018-6-26 09:36
数组zamb没有初始化或赋值
谢谢您的回答,但是在主程序里有赋值语句,而且我在call subroutine前方插入print *, zamb (1:kms),输出的值是正确的;
而且如果zamb没有正确赋值,不可能call lineplu_v1的时候,参数传递是正确的啊。(我在lineplu_v1变量声明下方插入print*, locat(1:layers),输出值正确,和zamb (1:kms)完全一样。
我在想subroutine里声明变量的时候是否有什么因素会造成参数传递错误? 藍原なみだ 发表于 2018-6-26 13:22
谢谢您的回答,但是在主程序里有赋值语句,而且我在call subroutine前方插入print *, zamb (1:kms),输出 ...
函数的输入参数顺序混淆了?
一个函数有超过二位数的输入值,看走眼也是完全有可能的 subroutine的声明部分, 請列出各"虛參"的type/dimension宣告
CALL lineplu_v1(...). CALL doubplu_v1(...), 請列出各"實參"的type/dimension宣告
本帖最后由 藍原なみだ 于 2018-6-27 19:23 编辑
chiangtp 发表于 2018-6-26 15:10
subroutine的声明部分, 請列出各"虛參"的type/dimension宣告
CALL lineplu_ ...
subroutine lineplu_v1的宣告:
REAL*8 ALPHA,AREA,B,CO2,COMG,CN2,CNMG,DS,DZ,DENSEA,DENSEP,DENSEW,
+DIAMM,E,FDO,FDN,FRACO,FRACN,FSAL,FTEMP,FGO,FGN,G,GAMMA,HO2,HN2,
+KOLN,KOLO,L,LAMBDA,MOMENT,N,PI,PO,PN,PSTD,PZ,QSCFM,QSCMS,QW,QGAS,
+RB,RGAS,SALAMB,SALPLU,TAMB,TPLUME,TSTD,V,VB,VBUB,VG,VGUESS,
+YO2,YN2,Z,AA,BB,CC,BNOT,LNOT,ELEV,DT,TE(1000),XLOC,DEPTH,
+CO2M(1000),LOCAT(1000),DOAMB,COMGP,CNMGP,WSEL,PATM,SAL(1000),
+DIFFEL,GROSSMT,FGONOT,DNAMB,DMPR,TAVG,SUMTEMP,SUMSAL,
+LAMBNOT,FRCONOT,RBNOT,H,DYDX(8),Y(8),YOUT(8),
+DENSE20,OTEFF,FRNOT,VDIFF,FR,BUOY,DCO2,QGFRAC,LDIFF,TDS(1000),
+JDAY,EL(70),DELTAC,COMGNOT,ELEVT,QWT,TPLUMET,COMGPT,QWD(500),
+PWD(500),BWD(500),AWD(500),
+HWITH,HCELL,JULDAY,BTOP,BEQUIV
INTEGER II,IJ,IK,IN,JJ,LL,NEQN,NN,MI,JK,JL,LAKE,LAYTOP
+LAYERS,KM,KN,KO,KP,ROWS,KQ,KR,KU,KV,KW,KX,KY,KZ,KS,LAYDIFF,YEAR
INTEGER NELS
subroutine doubplu_v1的宣告:
REAL*8 ALPHA,ALPHAA,ALPHAI,ALPHAO,AREA,B,BO,BH(1000),CO2,CO2H(1000),COMG,CN2,
+CN2H(1000),CNMG,DS,DZ,DENSEA,DENSEAH(1000),DENSEP,DENSEW,DENSEWH(1000),
+DIAMM,E,EH(1000),EO,EOH(1000),FDO,FDOO,FDN,FDNO,FRACO,FRACN,FSAL,FSALO,
+FTEMP,FTEMPO,FGO,FGOO,FGN,FGNO,G,GAMMA,HO2,HO2H(ID),HN2,HN2H(ID),
+KOLN,KOLNH(1000),KOLO,KOLOH(1000),L,LAMBDA,MOMENT,MOMENTO,N,PI,PO,
+POH(1000),PN,PNH(1000),PSTD,PZ,QSCFM,QSCMS,QW,QWO,QGAS,
+RB,RB(1000),RGAS,SALAMB,SALPLU,SALPLUH(1000),SALPLUO,SALPLUOH(1000),TAMB,
+TAMBH(1000),TPLUME,TPLUMEH(1000),TPLUMEO,TPLUMEOH(1000),TSTD,
+V,VH(1000),VI,VO,VOH(1000),VB,VBH(1000),VBUB,VG,VGUESS,VGUESSO,
+YO2,YN2,Z,AA,BB,CC,BNOT,LNOT,ELEV,DT,TE(1000),XLOC,DEPTH,
+CO2M,LOCAT(1000),DOAMB,
+COMGP,COMGPH(1000),CNMGP,CNMGPH(1000),WSEL,PATM,SAL(1000),
+DIFFEL,GROSSMT,FGONOT,DNAMB,DMPR,TAVG,SUMTEMP,SUMSAL,
+LAMBNOT,FRCONOT,RBNOT,H,DYDX(8),Y(8),YOUT(8),
+DENSE20,OTEFF,FRNOT,FRNOTO,VDIFF,FR,BUOY,DCO2,QGFRAC,LDIFF,TDS(1000),
+JDAY,EL(70),DELTAC,COMGNOT,ELEVT,ELEVOB,QWT,QWOB,TPLUMET,TPLUMEOB,
+COMGPT,COMGPOB,QWD(500),PWD(500),BWD(500),AWD(500),
+HWITH,HCELL,JULDAY,BTOP,BOB,BEQUIV
INTEGER II,IJ,IK,IN,JJ,LL,NEQN,NN,MI,JK,JL,LAKE,LAYTOP,LAYOB,
+LAYERS,KM,KN,KO,KP,ROWS,KQ,KR,KU,KV,KW,KX,KY,KZ,KS,LAYDIFF,YEAR
INTEGER NELS,ID,IDM
各个实参的宣告:INTEGER :: iyr, imon, iday, ihr
INTEGER :: im, im1, i1, jm, jm1, j1, km, km1, k1, ndx, ndy, ndz, nts, &
& ndim, maxnz, nw, inw, ibdwd, ifirst, ilast, jfirst, jlast
REAL(8) :: wselev, dfelev, dflgth, hcell, rjulday, lambnot, diamm
REAL(8) :: elevt, qwt, tplumt, comgpt, tplum0, comgp0, qscfm, frconot
REAL(8), DIMENSION (1:km1) :: zamb, Tamb, DOamb ! B.C.
REAL(8), DIMENSION (1:km1) :: qwd ! Outflow rate
REAL(8), DIMENSION (1:km1) :: bwd ! Radius of circular plume
REAL*8 :: oteff
INTEGER :: nn, inn, i, j, k, kk, l, k1s, kms, nwl, ktop, kob, ksrc, plmdim, itr
我今天尝试强制把locat(1:layers)的正确值在subroutine里赋值,结果运行程序还是出现severe (174) segmentation fault。网上查了一下,可能是数组太大了,于是设定了unlimited stack,并且编译语句后面加上 -heap-arrays,但没有用...参数传递仍然不正确。
藍原なみだ 发表于 2018-6-27 19:19
subroutine lineplu_v1的宣告:
REAL*8 ALPHA,AREA,B,CO2,COMG,CN2,CNMG,DS,DZ,DENSEA,DENSEP,DENSEW,
1. REAL(8) 是 REAL(KIND=8),REAL*8 是 8-byte REAL, 兩者不一定相同 (compiler dependent)
如果有問題, compile-time 應該就知道, 所以就不是這個問題
建議你通通改為 REAL*8, 或是
INTEGER, PARAMETER :: r8=SELECTED_REAL_KIND(P=15)
REAL(KIND=r8) :: ...
2. 請問你的 compiler ?
3. 請告知 完整的 SUBROUTINE title
SUBROUTIEN doubplu_v1(...)
SUBROUTINE lineplu_v1(...)
4. 請先自己檢查 "虛參"與"實參"的對應 是否一致
5. ksrc=?, km1=?
REAL(8), DIMENSION (1:km1) :: qwd, bwd
CALL lineplu_v1(..., qwd(1:ksrc), bwd(1:ksrc), ...) chiangtp 发表于 2018-6-27 20:28
1. REAL(8) 是 REAL(KIND=8),REAL*8 是 8-byte REAL, 兩者不一定相同 (compiler dependent)
如果有 ...
1. 虛參CO2M有問題, 對應的實參是 DOamb(1:kms)
in SUBROUTINE DOUBPLU_v1,REAL*8 :: CO2M
in SUBROUTINE LINEPLU_v1, REAL*8 :: CO2M(1000)
2. 實參 salamb 與 patm 的 type?
3. runtime時, 請確認: km1=1000, krsc=500 4. 實參: CALL ABC(..., zamb (1:kms), Tamb (1:kms), DOamb(1:kms), ..., qwd(1:ksrc), bwd(1:ksrc), ...), array-setction的用法, 沒有必要
--->CALL ABC(..., zamb, Tamb, DOamb, ..., qwd, bwd, ...) 應該就是錯在這裡: in SUBROUTINE DOUBPLU_v1
REAL*8 :: CO2M --->REAL*8 :: CO2M(1000)
页:
[1]
2