The program below allocates a polymorphic derived type variable from a SOURCE expression in ALLOCATE statement. The SOURCE itself becomes allocated as a result of a function call with allocatable return type. This seemingly causes the allocation of the source's derived type components to get lost in a memory leak.
If you know what is going on here, I would appreciate your help!
module m implicit none type :: derived_type ! causes 8 bit memory leak per allocation integer(8), allocatable :: alloc_comp ! (*) end type contains ! function with allocatable polymorphic result function make_class() class(derived_type), allocatable :: make_class ! (**) allocate(make_class) ! this allocation apparently gets lost allocate(make_class%alloc_comp) end function end module program p use m implicit none integer :: ii ! multiply leak by number of itterations do ii = 1,10 call cause_mem_leak() end do contains ! assign allocatable polymorphic function result to local variable subroutine cause_mem_leak() class(derived_type), allocatable :: my_class ! source expression gets allocated inside the allocation statement allocate(my_class, source = make_class()) ! no help here: deallocate(my_class%alloc_comp) deallocate(my_class) end subroutine end program
Valgrind detects 80 bit memory leak on my unix 64 bit Intel® Core™2 Quad CPU Q9400 @ 2.66GHz × 4 system.
- (*) change to pointer here, and everything is fine.
- (**) change to type here and get a runtime crash:
"forrtl: severe (153): allocatable array or pointer is not allocated"
- However, both changes made simultaneously bring back the leak again.
- Also, changing all 'class' into 'type' (e.g. pre-F2003 standard) solves all problems.
Allocating the SOURCE expression inside an ALLOCATE statement. The intel docs say:
"If [..] source-expr is specified, it must not be allocated in the ALLOCATE statement in which it appears"
The expression 'make_class()', which triggers the allocation of the SOURCE, is part of the ALLOCATE statement.
However, the actual allocation of the SOURCE is done by second, nested ALLOCATE statement inside the 'make_class()' function.
Does that still make the code invalid?
If so, what is the Fortran way to assign an allocatable polymorphic function result to a variable?
(Without the "realloc-lhs in assignment to polymorphic" F2008 feature)?
Thank you, with regards