f90中的内存损坏

时间:2017-05-25 13:23:09

标签: fortran gfortran memory-corruption

我有以下代码。

      PROGRAM CTS
        implicit none
!C     driver for routine fourn
      INTEGER NDAT,NDIM
      PARAMETER(NDIM=1,NDAT=1024)
      INTEGER i,idum,isign,j,k,l,nn(NDIM)
      REAL data1(NDAT),data2(NDAT),ran1 ,x,dx 
      REAL,DIMENSION(:),ALLOCATABLE::F,F1


    allocate(F(NDAT),F1(NDAT))
    x=1.
    dx = (200.-1.)/real(NDAT)
   nn(1)=NDAT
    do i=1,NDAT
    F1(i) =atan(x-100)
    x= x + dx
   enddo
x=1.


    x=1. 
  isign=1
      call fo(F1,nn,1,isign)

  open(1,file="zresult.dat",status="replace")
 do i=1,NDAT
 write(1,*)x,F1(i)*dx
x= x + dx
enddo 


stop


       END
!!!!!!!!!!!!!!!!!!!!!!!!!!
      SUBROUTINE fo(data,nn,ndim,isign)
      INTEGER isign,ndim,nn(ndim)
      REAL data(*)
      INTEGER i1,i2,i2rev,i3,i3rev,ibit,idim,ifp1,ifp2,ip1,ip2,ip3,k1,&
      k2,n,nprev,nrem,ntot
      REAL tempi,tempr
      DOUBLE PRECISION theta,wi,wpi,wpr,wr,wtemp
      ntot=1
      do 11 idim=1,ndim
        ntot=ntot*nn(idim)
11    continue
      nprev=1
      do 18 idim=1,ndim
        n=nn(idim)
        nrem=ntot/(n*nprev)
        ip1=2*nprev
        ip2=ip1*n
        ip3=ip2*nrem
        i2rev=1
        do 14 i2=1,ip2,ip1
          if(i2.lt.i2rev)then
            do 13 i1=i2,i2+ip1-2,2
              do 12 i3=i1,ip3,ip2
                i3rev=i2rev+i3-i2
                tempr=data(i3)
                tempi=data(i3+1)
                data(i3)=data(i3rev)
                data(i3+1)=data(i3rev+1)
                data(i3rev)=tempr
                data(i3rev+1)=tempi
12            continue
13          continue
          endif
          ibit=ip2/2
1         if ((ibit.ge.ip1).and.(i2rev.gt.ibit)) then
            i2rev=i2rev-ibit
            ibit=ibit/2
          goto 1
          endif
          i2rev=i2rev+ibit
14      continue
        ifp1=ip1
2       if(ifp1.lt.ip2)then
          ifp2=2*ifp1
          theta=isign*6.28318530717959d0/(ifp2/ip1)
          wpr=-2.d0*sin(0.5d0*theta)**2
          wpi=sin(theta)
          wr=1.d0
          wi=0.d0
          do 17 i3=1,ifp1,ip1
            do 16 i1=i3,i3+ip1-2,2
              do 15 i2=i1,ip3,ifp2
                k1=i2
                k2=k1+ifp1
                tempr=sngl(wr)*data(k2)-sngl(wi)*data(k2+1)
                tempi=sngl(wr)*data(k2+1)+sngl(wi)*data(k2)
                data(k2)=data(k1)-tempr
                data(k2+1)=data(k1+1)-tempi
                data(k1)=data(k1)+tempr
                data(k1+1)=data(k1+1)+tempi
15            continue
16          continue
            wtemp=wr
            wr=wr*wpr-wi*wpi+wr
            wi=wi*wpr+wtemp*wpi+wi
17        continue
          ifp1=ifp2
        goto 2
        endif
        nprev=n*nprev
18    continue
      return
      END
!!!!!!!!!!!

问题是如果我没有分配F1并放置REAL F1(NDAT),代码运行没有任何问题,但是当我分配F1时,我将收到以下错误 我已经尝试了所有可能性来理解正在发生的事情-fcheck=all等等。它似乎是内存损坏。

*** Error in `./out': free(): invalid next size (normal): 0x088a7f20 ***

Program received signal SIGABRT: Process abort signal.

Backtrace for this error:
#0  0xB76BE133
#1  0xB76BE7D0
#2  0xB77C73FF
#3  0xB77C7424
#4  0xB74E4686
#5  0xB74E7AB2
#6  0xB751EFD2
#7  0xB75294C9
#8  0xB752A13C
#9  0xB7777607
#10  0xB776EECF
#11  0xB776EFB9
#12  0xB76BDA93
#13  0xB77D733B
#14  0xB74E9230
#15  0xB74E928C
#16  0xB76C09E7
#17  0x80496D4 in cts at z2.f90:33
Aborted (core dumped)

你能帮我找出问题所在。 非常感谢你

1 个答案:

答案 0 :(得分:0)

如果在子例程之后移动END,则在子例程之前放置CONTAINS以使其内部程序,更改假定的大小数组

data(*)

假设形状数组

data(:)

(仅使用data(NDAT)也有帮助)

然后您可以将代码编译为

gfortran-7 -Wall -Wno-unused-variable -fcheck=all memcorr.f90

并获得明确的消息

> ./a.out 
At line 63 of file memcorr.f90
Fortran runtime error: Index '1025' of dimension 1 of array 'data' above upper bound of 1024

这意味着您正在越过界限访问阵列。

第63行是:

 data(i3)=data(i3rev)

因此i3i3rev太大(大于NDAT)。你必须找出原因并解决这个问题。

重点是:使用显式接口,假定形状数组和所有其他Fortran 90可以帮助您找到错误。

最好的办法是使用模块来完成所有子程序和功能。