肯定是valgrind的记忆丧失

时间:2014-01-20 15:36:18

标签: fortran valgrind

我有以下Fortran代码的这一部分,在allocate(temp)处,valgrind说明了内存丢失。我在分配这些数据方面有什么错误吗?

subroutine insert_linked_list_grids(l,ncell,nclust,corner,headlev)
    implicit none

    integer :: ig, jg, kg, k, l, m1, m2, m3, nx, ny, nz, ncell, &
         nclust, bsaux, bnaux, bwaux, beaux, bbaux, btaux

    double precision :: dx, dy, dz, dxaux, dyaux, dzaux

    double precision, dimension(24,maxcl) :: corner

    type(level_components1), pointer :: temp, curr
    type(level_components1), dimension(ltop), target :: headlev


    dx    = headlev(l)%hx
    dy    = headlev(l)%hy
    dz    = headlev(l)%hz
    dxaux = headlev(l-1)%hx
    dyaux = headlev(l-1)%hy
    dzaux = headlev(l-1)%hz

    !nullify(headlev(l)%next)
    curr => headlev(l)
    headlev(l)%npatches = 0

    !calculating ix, iy, iz, mx, my, mz
    write(*,*) 'total number of cluster =', nclust
    do k=1,nclust 

       headlev(l)%npatches = headlev(l)%npatches +1

       ig = nint(r*(corner(1,k) - 0.5d0*dxaux - a1)/dxaux ) + 1 
       jg = nint(r*(corner(2,k) - 0.5d0*dyaux - a2)/dyaux ) + 1
       kg = nint(r*(corner(3,k) - 0.5d0*dzaux - a3)/dzaux ) + 1

       !write(*,*) "cluster = ", k,"ig = ", ig,"jg = ", jg,&
       !        "kg = ",kg

       nx = nint(r*(corner(10,k)-corner(1,k) + dxaux)/dxaux)
       ny = nint(r*(corner(5,k)-corner(2,k)  + dyaux)/dyaux)
       nz = nint(r*(corner(15,k)-corner(3,k) + dzaux)/dzaux)

       !write(*,*) "cluster = ", k,"nx = ", nx,"ny = ", ny,&
       !        "nz = ",nz

       call bc_linked_list(ig,jg,kg,nx,ny,nz,dx,dy,dz,bwaux,beaux,&
            bsaux,bnaux,bbaux,btaux,headlev) 

       allocate(temp)

       temp%grid%ix = ig
       temp%grid%iy = jg
       temp%grid%iz = kg
       temp%grid%mx = nx
       temp%grid%my = ny
       temp%grid%mz = nz
       temp%grid%iu = 1 + ncell
       temp%grid%bw = bwaux
       temp%grid%be = beaux
       temp%grid%bs = bsaux
       temp%grid%bn = bnaux
       temp%grid%bb = bbaux
       temp%grid%bt = btaux

       m1 = temp%grid%mx + 1 + 2*nbc
       m2 = temp%grid%my + 1 + 2*nbc
       m3 = temp%grid%mz + 1 + 2*nbc
       ncell = ncell + m1*m2*m3

       nullify(temp%next)
       curr%next => temp
       curr => temp


    end do

    return

  end subroutine insert_linked_list_grids

1 个答案:

答案 0 :(得分:3)

我希望valgrind警告你,当子程序返回temp超出范围并且实际上是收获时,temp所指向的内存不会被收获;这看起来像是一个规范的内存泄漏给我。

您可以在子例程结束前解除分配temp

或者你可以使temp成为可分配的数组,在这种情况下,编译器负责生成代码,该代码在子例程返回时占用分配的内存。通常,使用现代(Fortran 2003)编译器allocatable是比pointer动态管理内存的更好途径,因为编译器负责内存释放。当然,在某些情况下只有一个指针可以做。