Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29279 Discussions

OOP function return class memory leak

Patrice_l_
Beginner
631 Views

Hi,

I want to discuss a case/bug where the return of a function is not properly deallocated when it is declared class. When return as type everything is clean. There is no need for an assignment and final subroutine but it help see what happens.

It seems to me also that the compiler should complain about the intrisic class copy when the assignment is not available, but it figures the copy correctly, but after fails to deallocate the temporary object as you can see when compare output with type and class.

Is it possible to avoid the additional copy from the temporary object into sm, and directly use sm as recipient for the output function ? I know this is the behavior when using a subroutine.

 

module tata
        implicit none
  type bar
    integer, allocatable  :: ia(:), ja(:)
    contains
            final:: destroy
            procedure,pass :: copy
            generic,public :: assignment(=) => copy
  end type
  contains
subroutine copy(t2,t1)
        class(bar),intent(in) :: t1
        class(bar),intent(out) :: t2
        print *,'copy class'
        allocate(t2%ia(size(t1%ia)) ,source=t1%ia)
        allocate(t2%ja(size(t1%ja)) ,source=t1%ja)
end subroutine
function assign1(t1) result(t2)
        class(bar),intent(in) :: t1
        class(bar),allocatable :: t2
        allocate(t2)
        allocate(t2%ia(size(t1%ia)) ,source=t1%ia)
        allocate(t2%ja(size(t1%ja)) ,source=t1%ja)
end function
subroutine destroy(this)
        type(bar) :: this
        if(allocated(this%ia)) then
                deallocate(this%ia,this%ja)
                print *,'destroy  class'
        else
                print *,'destroy empty class'
        end if

end subroutine
subroutine toto
  type(bar), allocatable :: sm,sm2
  integer :: i

  allocate(sm)
  allocate(sm2)
  allocate(sm%ia(100),sm%ja(100))
  allocate(sm2%ia(1000),sm2%ja(1000))

  do i=1,2
        deallocate(sm)
        allocate(sm)
        sm=assign1(sm2)
  end do

deallocate(sm2)
end subroutine
end module
program testmv3
        use tata
        implicit none
call toto()
end program testmv3

With class :

 destroy  class
 destroy empty class
 copy class

With type :

destroy  class
 destroy empty class
 copy class
 destroy  class

 

0 Kudos
3 Replies
Steven_L_Intel1
Employee
631 Views

1. The memory leak is fixed in 15.0 update 1, due out very soon.

2. Why do you think intrinsic copy should be an error here? sm and assign are the same declared type (and even the same dynamic type.) Fortran 2003's wording about this is somewhat unclear but Fortran 2008 says "the declared types of the variable and expr shall conform as specified in Table 7.8" where the table says the types must be the same. This all looks correct to me.

3. No, you can't avoid the copy - the semantics are different than when passing the variable as an argument to a subroutine.

0 Kudos
Patrice_l_
Beginner
631 Views

Ok thank you.

For the point 2, because of that  :  error #8304: In an intrinsic assignment statement, variable shall not be polymorphic.  when i try to do class=class without an assign operator. Unless it is added in update 1.

 

0 Kudos
Steven_L_Intel1
Employee
631 Views

No - that's a different thing. Fortran 2003 doesn't allow intrinsic assignment to a polymorphic variable, Fortran 2008 does. But Intel Fortran hasn't yet added that F2008 feature.

0 Kudos
Reply