The following code results in a memory leak when compiled with ifort 14.0.3
module testmod type :: obj integer, allocatable :: i contains procedure :: add => obj_add procedure :: copy => obj_copy generic :: operator(+) => add end type obj contains subroutine obj_copy(this, source) implicit none class(obj) :: this class(obj) :: source this%i=source%i end subroutine obj_copy function obj_add(A, B) result(C) implicit none class(obj), intent(in) :: A, B class(obj), allocatable :: C allocate(C) allocate(C%i) C%i=A%i+B%i end function obj_add end module testmod program leak use testmod implicit none class(obj), allocatable :: A, B, C allocate(A, B, C) A%i=1 B%i=2 call C%copy(A+B) deallocate(A, B, C) end program leak
When compiled with
ifort -g -o leak leak.f90 -assume realloc_lhs
Valgrind reports
==21260== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2
==21260== at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21260== by 0x419BF8: for_alloc_allocatable (in /mnt/data/PhD/Fortran/bugs/operator-leak/leak)
==21260== by 0x402F41: testmod_mp_obj_add_ (leak.f90:26)
==21260== by 0x403431: MAIN__ (leak.f90:39)
==21260== by 0x402BC5: main (in /mnt/data/PhD/Fortran/bugs/operator-leak/leak)
think this might also be the cause of the problems encountered in this thread https://software.intel.com/en-us/forums/topic/487142 from some time ago.
If I change the result dummy to
type(obj) :: C
and skip the allocation stuff in obj_add, then the leak is avoided. However, this also results in losing polymorphism, which is undesirable. If the procedure is made as a subroutine, I lose the ability to use it as an operator. Does anybody have any suggestion to work around this issue?
Best regards
Emil Sørensen