主题:内存泄漏问题,求助
The test code is as bellow:
module DataMOD
type data
real :: x
type(data),pointer :: next=>null()
! contains
! FINAL :: RemoveData
end type data
interface operator(+)
module procedure DataAdd
end interface operator(+)
interface assignment(=)
module procedure DataAssign
end interface assignment(=)
contains
recursive function DataAdd( d1, d2) result(d)
implicit none
type(data),intent(in) :: d1, d2
type(data) :: d
type(data),pointer :: pd1, pd2, pd
d%x = d1%x + d2%x
if(associated(d1%next))then
call RemoveData(d)
allocate(d%next)
pd1 => d1%next
pd2 => d2%next
pd => d%next
pd = pd1 + pd2
endif
end function DataAdd
recursive subroutine DataAssign(od, id)
implicit none
type(data),intent(in) :: id
type(data),intent(out) :: od
od%x = id%x
if(associated(id%next))then
call RemoveData(od)
allocate(od%next)
call DataAssign(od%next, id%next)
endif
end subroutine DataAssign
recursive function trans(d) result(od)
implicit none
type(data),intent(in) :: d
type(data) :: od
od%x = d%x + 5.
if(associated(d%next))then
call RemoveData(od)
allocate(od%next)
od%next = trans(d%next)
endif
end function trans
recursive subroutine RemoveData(D)
implicit none
type(data) :: D
if(associated(D%next)) then
call RemoveData(D%next)
deallocate(D%next)
endif
write(*,*)"RemoveData"
end subroutine RemoveData
subroutine ddd
! use DataMOD
implicit none
type(data) :: d1, d2, d, dd
d1%x = 1.
d2%x = 2.
allocate(d1%next, d2%next)
d1%next%x = 3.
d2%next%x = 4.
d = d1 + d2
dd = trans(d1)
call RemoveData(d1)
call RemoveData(d2)
call RemoveData(d)
call RemoveData(dd)
end subroutine ddd
end module DataMOD
program test
use DataMOD
call ddd
end program test
After run in valgrind, the memory leakage errors are:
==6470== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==6470== at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6470== by 0x400D42: __datamod_MOD_dataadd (test.f90:28)
==6470== by 0x400999: __datamod_MOD_ddd (test.f90:82)
==6470== by 0x400E10: MAIN__ (test.f90:97)
==6470== by 0x400E46: main (test.f90:95)
==6470==
==6470== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==6470== at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6470== by 0x400B9F: __datamod_MOD_trans (test.f90:55)
==6470== by 0x4009E6: __datamod_MOD_ddd (test.f90:84)
==6470== by 0x400E10: MAIN__ (test.f90:97)
==6470== by 0x400E46: main (test.f90:95)
==6470==
==6470== LEAK SUMMARY:
==6470== definitely lost: 32 bytes in 2 blocks
==6470== indirectly lost: 0 bytes in 0 blocks
==6470== possibly lost: 0 bytes in 0 blocks
==6470== still reachable: 0 bytes in 0 blocks
==6470== suppressed: 0 bytes in 0 blocks
how to avoid these memory leakage without using the FINAL subroutine? how to modified the above code?
module DataMOD
type data
real :: x
type(data),pointer :: next=>null()
! contains
! FINAL :: RemoveData
end type data
interface operator(+)
module procedure DataAdd
end interface operator(+)
interface assignment(=)
module procedure DataAssign
end interface assignment(=)
contains
recursive function DataAdd( d1, d2) result(d)
implicit none
type(data),intent(in) :: d1, d2
type(data) :: d
type(data),pointer :: pd1, pd2, pd
d%x = d1%x + d2%x
if(associated(d1%next))then
call RemoveData(d)
allocate(d%next)
pd1 => d1%next
pd2 => d2%next
pd => d%next
pd = pd1 + pd2
endif
end function DataAdd
recursive subroutine DataAssign(od, id)
implicit none
type(data),intent(in) :: id
type(data),intent(out) :: od
od%x = id%x
if(associated(id%next))then
call RemoveData(od)
allocate(od%next)
call DataAssign(od%next, id%next)
endif
end subroutine DataAssign
recursive function trans(d) result(od)
implicit none
type(data),intent(in) :: d
type(data) :: od
od%x = d%x + 5.
if(associated(d%next))then
call RemoveData(od)
allocate(od%next)
od%next = trans(d%next)
endif
end function trans
recursive subroutine RemoveData(D)
implicit none
type(data) :: D
if(associated(D%next)) then
call RemoveData(D%next)
deallocate(D%next)
endif
write(*,*)"RemoveData"
end subroutine RemoveData
subroutine ddd
! use DataMOD
implicit none
type(data) :: d1, d2, d, dd
d1%x = 1.
d2%x = 2.
allocate(d1%next, d2%next)
d1%next%x = 3.
d2%next%x = 4.
d = d1 + d2
dd = trans(d1)
call RemoveData(d1)
call RemoveData(d2)
call RemoveData(d)
call RemoveData(dd)
end subroutine ddd
end module DataMOD
program test
use DataMOD
call ddd
end program test
After run in valgrind, the memory leakage errors are:
==6470== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==6470== at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6470== by 0x400D42: __datamod_MOD_dataadd (test.f90:28)
==6470== by 0x400999: __datamod_MOD_ddd (test.f90:82)
==6470== by 0x400E10: MAIN__ (test.f90:97)
==6470== by 0x400E46: main (test.f90:95)
==6470==
==6470== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==6470== at 0x4C2993D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6470== by 0x400B9F: __datamod_MOD_trans (test.f90:55)
==6470== by 0x4009E6: __datamod_MOD_ddd (test.f90:84)
==6470== by 0x400E10: MAIN__ (test.f90:97)
==6470== by 0x400E46: main (test.f90:95)
==6470==
==6470== LEAK SUMMARY:
==6470== definitely lost: 32 bytes in 2 blocks
==6470== indirectly lost: 0 bytes in 0 blocks
==6470== possibly lost: 0 bytes in 0 blocks
==6470== still reachable: 0 bytes in 0 blocks
==6470== suppressed: 0 bytes in 0 blocks
how to avoid these memory leakage without using the FINAL subroutine? how to modified the above code?