我有以下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
答案 0 :(得分:3)
我希望valgrind警告你,当子程序返回temp
超出范围并且实际上是收获时,temp
所指向的内存不会被收获;这看起来像是一个规范的内存泄漏给我。
您可以在子例程结束前解除分配temp
。
或者你可以使temp
成为可分配的数组,在这种情况下,编译器负责生成代码,该代码在子例程返回时占用分配的内存。通常,使用现代(Fortran 2003)编译器allocatable
是比pointer
动态管理内存的更好途径,因为编译器负责内存释放。当然,在某些情况下只有一个指针可以做。