2017-05-25 159 views
0

我有以下代碼。f90中的內存損壞

 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) 

請幫我找出問題所在。 謝謝你這麼多

+0

當其他人應該理解它時,請使用一些更好的代碼格式。你的縮進是可怕的,完全不一致。我相信它可以縮短得多(見[mcve])。 –

+0

@高性能標記你能解釋更多如何使用stat? –

+0

'allocate(...,stat = integer_variable)',但它不會幫你在這裏。由於分配,錯誤不會發生,在分配過程中不會發生。看到答案。 –

回答

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的東西,這將幫助你發現漏洞。

最好的事情是使用模塊爲您的所有子程序和功能。

+0

非常感謝你 –

+0

但爲什麼它不會發生在主要我把F(NDAT),只有當我分配F1它發生??? –

+0

發生錯誤**總是**。有時你根本沒注意到。 Buggy程序未定義。它可以做任何事情。請參閱https://en.wikipedia。org/wiki/Undefined_behavior –