wxy 发表于 2017-9-15 17:51:49

动态数组内存问题

运行到24行时出现内存错误提示,不明白什么原因Program weather
Implicit None

Integer l, i, j, m, daysinyear, k, mm, e, z
Integer, Allocatable :: site1(:), site2(:), year(:), month(:), day(:)

Real, Allocatable :: lat(:), lon(:), h(:), tmax(:), tmin(:), lonx(:), laty(:)
Integer :: ave, ier
Real :: h2

Character (45) :: filename = 'SURF_CLI_CHN_MUL_DAY-TEM-12001-123456.txt'
Character (8) :: outfile = '12345678'
Character (Len=20) :: line

!=====================================
Open (5, File='D:\气象数据New\经纬度高程\经纬度高程.txt')
e = 2421
Allocate (site2(e), lonx(e), laty(e))
Do z = 1, e
    Read (5, *) site2(z), lonx(z), laty(z), h2
    write(*,*) site2(z), lonx(z), laty(z), h2
End Do
Deallocate (site2, lonx, laty)
Close (5)
Do l = 2010, 2015
    Do j = 1, 12
      Write (filename(32:37), '(i6)') l*100 + j
      Open (Unit=11, File='D:\气象数据\气温\'//filename, Action='READ')

      m = 0
      Do
      Read (11, *, Iostat=ier) line
      If (ier==-1) Exit ! end-of-file
      m = m + 1
      End Do
      Allocate (site1(m), lat(m), lon(m), h(m), year(m), month(m), day(m), tmax(m), tmin(m))

      Rewind (11)
      mm = 0
      Do i = 1, m
      mm = mm + 1
      Read (11, *) site1(mm), lat(mm), lon(mm), h(mm), year(mm), month(mm), day(mm), ave, tmax(mm), tmin(mm)
      lat(mm) = lat(mm)/100
      lon(mm) = lon(mm)/100

      tmax(mm) = tmax(mm)*0.1
      tmin(mm) = tmin(mm)*0.1
      If (h(mm)>=100000) Then
          h(mm) = (h(mm)-100000)
      End If
      h(mm) = h(mm)*0.1
      If (tmax(mm)==3270.0 .Or. tmax(mm)==3276.6 .Or. tmin(mm)==3270.0 .Or. tmin(mm)==3276.6) mm = mm - 1

      End Do
      Close (Unit=11)

      Do k = 1, daysinyear(l, j)
      Write (outfile(1:8), '(i8)') l*10000 + j*100 + k
      Open (Unit=15, File='D:\气象数据\tmax\'//outfile//'.txt')
      Open (Unit=16, File='D:\气象数据\tmin\'//outfile//'.txt')
      Do i = 1, mm

          If (l==year(i) .And. j==month(i) .And. k==day(i)) Then


            Do While (site1(i)==site2(z))
            Write (15, '(i5,2x,f6.2,2x,f5.2,2x,f12.4,2x,f12.4,2x,f6.2)') &
            &site1(i), lon(i), lat(i), lonx(z), laty(z), tmax(i) + (h(i)/100)*0.6
! "(i5,2x,f5.2,2x,f6.2,2x,f5.0,2x,i5,2x,i2,2x,i2,2x,f6.2)"
            Write (16, '(i5,2x,f6.2,2x,f5.2,2x,f12.4,2x,f12.4,2x,f6.2)') &
            &site1(i), lon(i), lat(i), lonx(z), laty(z), tmin(i) + (h(i)/100)*0.6
            Print *, site1(i), year(i), month(i), day(i)

            End Do

          End If
      End Do
      Close (Unit=15)
      End Do

      Deallocate (site1, lat, lon, h, year, month, day, tmax, tmin)
    End Do
End Do

End Program weather

!=======================================

Integer Function daysinyear(year, month)
Integer, Intent (In) :: year, month

Integer :: daysinmonth(12) = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]

If (((mod(year,4)==0) .And. (mod(year,100)/=0)) .Or. (mod(year,400)==0)) Then
    daysinmonth(2) = 29
Else
    daysinmonth(2) = 28
End If

daysinyear = daysinmonth(month)
End Function daysinyear

chiangtp 发表于 2017-9-15 21:31:02

line24: CLOSE(UNIT=5)?
不要用 UNIT= 0, 5, 6 對應到 diskfile (尤其是又有 READ/WRITE(*,...)時, compiler會暈車)

請試試看, 是不是這個問題

wxy 发表于 2017-9-16 00:15:03

本帖最后由 wxy 于 2017-9-16 00:29 编辑

chiangtp 发表于 2017-9-15 21:31
line24: CLOSE(UNIT=5)?
不要用 UNIT= 0, 5, 6 對應到 diskfile (尤其是又有 READ/WRITE(*,...)時, compile ...
额 我换成其他10,13等还是同样错误,我在运行时,到第24行运行都没问题,是16-24行这部分循环运行结束时报错,我想是不是后面67行这儿使用之前read内容时出错了

chiangtp 发表于 2017-9-16 00:31:23

wxy 发表于 2017-9-16 00:15
额 我换成其他10,13等还是同样错误

仍是 "运行到24行, CLOSE(UNIT=13), 出现内存错误提示"?
i.e., 還沒執行到 "Do l = 2010, 2015", 就runtime error?

請把 "program weather"+"经纬度高程.txt" 把包, 讓我download實際測試, 謝謝

chiangtp 发表于 2017-9-16 00:44:58

wxy 发表于 2017-9-16 00:15
额 我换成其他10,13等还是同样错误,我在运行时,到第24行运行都没问题,是16-24行这部分循环运行结束时报 ...

抱歉,
delete line 23: Deallocate (site2, lonx, laty)
END PROGRAM之前, 方可Deallocate (site2, lonx, laty),

后面 lines66-71这儿使用之前read内容:site2(z), lonx(z), laty(z)
subscript "z" 是不對的???

chiangtp 发表于 2017-9-16 01:05:32

chiangtp 发表于 2017-9-16 00:44
抱歉,
delete line 23: Deallocate (site2, lonx, laty)
END PROGRAM之前, 方可Deallocate (site2, lonx, ...

      REWIND(UNIT=11)
      mm = 0
      DO i = 1, m
      mm = mm + 1
      READ(11,*) site1(mm), lat(mm), lon(mm), h(mm), year(mm), month(mm), day(mm), ave, tmax(mm), tmin(mm)
      IF( tmax(mm)==3270.0 .OR. tmax(mm)==3276.6 .OR. tmin(mm)==3270.0 .OR. tmin(mm)==3276.6 ) THEN
          mm = mm - 1
          CYCLE
      END IF

      IF( h(mm) >= 100000.0 ) h(mm) = h(mm) - 100000.0
      h   (mm) = h   (mm)*0.1
      tmax(mm) = tmax(mm)*0.1
      tmin(mm) = tmin(mm)*0.1
      lon (mm) = lon (mm)/100.0
      lat (mm) = lat (mm)/100.0
      END DO
      CLOSE(UNIT=11)

      DO k = 1, daysinyear(l,j)
      WRITE(outfile(1:8),'(i8)') l*10000 + j*100 + k
      OPEN( UNIT=15, FILE='...' )
      OPEN( UNIT=16, FILE='...' )

      100 FORMAT(i5,2x,f6.2,2x,f5.2,2x,f12.4,2x,f12.4,2x,f6.2)
      DO i = 1, mm
          IF( l/=year(i) .OR. j/=month(i) .OR. k==day(i) ) CYCLE
          DO z = 1, e
            IF( site1(i) == site2(z) ) THEN
            WRITE(15,100) site1(i), lon(i), lat(i), lonx(z), laty(z), tmax(i)+(h(i)/100)*0.6
            WRITE(16,100) site1(i), lon(i), lat(i), lonx(z), laty(z), tmin(i)+(h(i)/100)*0.6
            WRITE(*,*) site1(i), year(i), month(i), day(i)
            END IF
          END DO
      END DO

      CLOSE(UNIT=15)
      END DO

chiangtp 发表于 2017-9-16 01:09:40

chiangtp 发表于 2017-9-16 01:05
      REWIND(UNIT=11)
      mm = 0
      DO i = 1, m



CLOSE(UNIT=15)
CLOSE(UNIT=16)
END DO

chiangtp 发表于 2017-9-16 01:18:35

chiangtp 发表于 2017-9-16 01:09


e = 2421
ALLOCATE( site2(e), lonx(e), laty(e) )

OPEN( UNIT=15, FILE='...' )
DO z = 1, e
    READ(15,*) site2(z), lonx(z), laty(z), h2
    WRITE(*,*) site2(z), lonx(z), laty(z), h2
END DO
CLOSE( UNIT=15 )

!-----------------

Do l = 2010, 2015
Do j = 1, 12
    WRITE(filename(32:37), '(i6)') l*100 + j
    OPEN( UNIT=11, FILE='...', ACTION='READ' )
    m = 0
    DO
      READ(11,*,IOSTAT=ier) line
      IF( ier == -1 ) EXIT ! end-of-file
      m = m + 1
    END DO
    ALLOCATE( site1(m), lat(m), lon(m), h(m), year(m), month(m), day(m), tmax(m), tmin(m) )

    REWIND( UNIT=11 )
    mm = 0
    DO i = 1, m
      mm = mm + 1
      READ(11,*) site1(mm), lat(mm), lon(mm), h(mm), year(mm), month(mm), day(mm), ave, tmax(mm), tmin(mm)
      IF( tmax(mm)==3270.0 .OR. tmax(mm)==3276.6 .OR. tmin(mm)==3270.0 .OR. tmin(mm)==3276.6 ) THEN
      mm = mm - 1
      CYCLE
      END IF

      IF( h(mm) >= 100000.0 ) h(mm) = h(mm) - 100000.0
      h   (mm) = h   (mm)*0.1
      tmax(mm) = tmax(mm)*0.1
      tmin(mm) = tmin(mm)*0.1
      lon (mm) = lon (mm)/100.0
      lat (mm) = lat (mm)/100.0
    END DO
    CLOSE( UNIT=11 )

    !-----

    DO k = 1, daysinyear(l,j)
      WRITE(outfile(1:8),'(i8)') l*10000 + j*100 + k
      OPEN( UNIT=15, FILE='...' )
      OPEN( UNIT=16, FILE='...' )

      100 FORMAT(i5,2x,f6.2,2x,f5.2,2x,f12.4,2x,f12.4,2x,f6.2)
      DO i = 1, mm
      IF( l/=year(i) .OR. j/=month(i) .OR. k==day(i) ) CYCLE
      DO z = 1, e
          IF( site1(i) == site2(z) ) THEN
            WRITE(15,100) site1(i), lon(i), lat(i), lonx(z), laty(z), tmax(i)+(h(i)/100)*0.6
            WRITE(16,100) site1(i), lon(i), lat(i), lonx(z), laty(z), tmin(i)+(h(i)/100)*0.6
            WRITE(*,*) site1(i), year(i), month(i), day(i)
          END IF
      END DO
      END DO
      CLOSE( UNIT=15 )
      CLOSE( UNIT=16 )
    END DO

    DEALLOCATE( site1, lat, lon, h, year, month, day, tmax, tmin )
END DO
END DO

DEALLOCATE( site2, lonx, laty )

END PROGRAM weather

chiangtp 发表于 2017-9-16 11:38:15

chiangtp 发表于 2017-9-16 01:18
e = 2421
ALLOCATE( site2(e), lonx(e), laty(e) )



1. 還是有點小錯:"k==day(i)"---> "k/=day(i)"
2. 改善Loop的效率: "IF(l/=year(i) .OR. j/=month(i))"往前提 (not function of "iday" loop)
3. 重要的subscripts: "l, j, k" ---> "iyear, imonth, iday", 可讀性高
4. 數理/Fortran的文化: "z"不宜為subscript "iz"可也
5. for REAL: "100" ---> "100.0"
INTEGER :: iyear, imonth, iday, nn

!-----------------

nn = 2421
ALLOCATE( site2(nn), lonx(nn), laty(nn) )

OPEN( UNIT=11, FILE='...' )
DO i = 1, nn
    READ(11,*) site2(i), lonx(i), laty(i)
END DO
CLOSE( UNIT=11 )

!-----------------

DO iyear= 2010, 2015
DO imonth = 1, 12
    WRITE(filename(32:37), '(i6)') iyear*100 + imonth
    OPEN( UNIT=11, FILE='...', ACTION='READ' )
    m = 0
    DO
      READ(11,*,IOSTAT=ier) line
      IF( ier == -1 ) EXIT ! end-of-file
      m = m + 1
    END DO
    ALLOCATE( site1(m), lat(m), lon(m), h(m), year(m), month(m), day(m), tmax(m), tmin(m) )

    REWIND( UNIT=11 )
    mm = 0
    DO i = 1, m
      mm = mm + 1
      READ(11,*) site1(mm), lat(mm), lon(mm), h(mm), year(mm), month(mm), day(mm), ave, tmax(mm), tmin(mm)
      IF( year(mm)/=iyear .OR. month(mm)/=imonth .OR. &
          tmax(mm)==3270.0 .OR. tmax(mm)==3276.6 .OR. tmin(mm)==3270.0 .OR. tmin(mm)==3276.6 ) THEN
      mm = mm - 1
      CYCLE
      END IF

      IF( h(mm) >= 100000.0 ) h(mm) = h(mm) - 100000.0
      h   (mm) = h   (mm)*0.1
      tmax(mm) = tmax(mm)*0.1
      tmin(mm) = tmin(mm)*0.1
      lon (mm) = lon (mm)/100.0
      lat (mm) = lat (mm)/100.0
    END DO
    CLOSE( UNIT=11 )

    !-----
    IF( mm == 0 ) CYCLE
    !-----

    DO iday = 1, daysinyear(iyear,imonth)
      WRITE(outfile(1:8),'(i8)') iyear*10000 + imonth*100 + iday
      OPEN( UNIT=15, FILE='...' )
      OPEN( UNIT=16, FILE='...' )

      100 FORMAT(i5,2x,f6.2,2x,f5.2,2x,f12.4,2x,f12.4,2x,f6.2)
      DO i = 1, mm
      IF( iday /= day(i) ) CYCLE
      DO j = 1, nn
          IF( site1(i) /= site2(j) ) CYCLE
          WRITE(15,100) site1(i), lon(i), lat(i), lonx(j), laty(j), tmax(i)+(h(i)/100.0)*0.6
          WRITE(16,100) site1(i), lon(i), lat(i), lonx(j), laty(j), tmin(i)+(h(i)/100.0)*0.6
          WRITE(*,*) site1(i), year(i), month(i), day(i)
      END DO
      END DO
      CLOSE( UNIT=15 )
      CLOSE( UNIT=16 )
    END DO

    DEALLOCATE( site1, lat, lon, h, year, month, day, tmax, tmin )
END DO
END DO

DEALLOCATE( site2, lonx, laty )

END PROGRAM weather

wxy 发表于 2017-9-16 13:11:58

本帖最后由 wxy 于 2017-9-16 13:21 编辑

chiangtp 发表于 2017-9-16 11:38
1. 還是有點小錯:"k==day(i)"---> "k/=day(i)"
2. 改善Loop的效率: "IF(l/=year(i) .OR. j/=month(i) ...
不好意思刚看到 非常感谢 ,我还是不太明白这个报错是什么意思,为甚末之前将deallocate放在下一个do循环之前就会报错,放在end program 之前就没事,deallocate不是将之前的动态数组内存释放掉吗,2. '/=,.or.'和‘==,.and.’这里有点转不过来,'/='不是‘不等于‘’吗
页: [1] 2
查看完整版本: 动态数组内存问题