I defined a derived type and ran into some problems with freeing up memory, although I wrote the final procedure. The code is as follows
module ModuleCoordinate implicit none type :: TCoordinate real(8),dimension(:),pointer :: Coordinate => NULL() contains procedure :: TCoordinateAssignment generic,public :: Assignment(=) => TCoordinateAssignment final :: TCoordinateDel end type TCoordinate interface TCoordinate module procedure :: TCoordinateInit end interface TCoordinate contains subroutine TCoordinateDel(self) type(TCoordinate),intent(inout) :: self if(associated(self%Coordinate))deallocate(self%Coordinate) end subroutine TCoordinateDel subroutine TCoordinateAssignment(O1,O2) class(TCoordinate),intent(out) :: O1 type(TCoordinate),intent(in) :: O2 if(associated(O2%Coordinate))allocate(O1%Coordinate,source=O2%Coordinate) end subroutine TCoordinateAssignment type(TCoordinate) function TCoordinateInit(IVal1,IVal2) result(self) real(8),intent(in) :: IVal1,IVal2 allocate(self%Coordinate(2)) self%Coordinate=(/IVal1,IVal2/) end function TCoordinateInit end module ModuleCoordinate
The verification code is as follows
program test implicit none integer(4),parameter :: NLoop=40000 integer(4) :: i do i=1,NLoop call TestMemory1() call TestMemory2() end do pause end program test subroutine TestMemory1() use ModuleCoordinate implicit none integer(4),parameter :: DN=10 integer(4) :: i type(TCoordinate),dimension(DN) :: a do i=1,DN a(i)=TCoordinate(1.0_8,1.0_8) end do end subroutine TestMemory1 subroutine TestMemory2() use ModuleCoordinate implicit none type(TCoordinate) :: b1,b2,b3,b4,b5,b6,b7,b8,b9,b10 b1=TCoordinate(1.0_8,1.0_8) b2=TCoordinate(1.0_8,1.0_8) b3=TCoordinate(1.0_8,1.0_8) b4=TCoordinate(1.0_8,1.0_8) b5=TCoordinate(1.0_8,1.0_8) b6=TCoordinate(1.0_8,1.0_8) b7=TCoordinate(1.0_8,1.0_8) b8=TCoordinate(1.0_8,1.0_8) b9=TCoordinate(1.0_8,1.0_8) b10=TCoordinate(1.0_8,1.0_8) end subroutine TestMemory2
It turns out that the TestMemory2 routine TestMemory2 OK, but TestMemory1 is not, which means that when an array of this derived type is declared, the final procedure does not work and there is a memory leak.
However, if I remove => NULL() right of the Coordinate in the definition of this derived type, both routines seem to work well.
What is the difference when the coordinate Coordinate freed? If this is important, then complier is ifort_2013_sp1.3.174.