2017-05-25 139 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 –