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

When final procedure run?

quaintchewster
Beginner
320 Views
It is really a confusing problem.

look this code. type aa and bb have their own final routines for
single object and an array of the object.
But type bb contains an 1D pointer of type aa.

When deallocate a pointer of type bb with rank 0, both it and its
pointer of aa can be finallized.

But, when deallocate a 1D pointer of type bb, only the bb array can be
finalized, its pointer to aa(:) can not be finalized. Why ??

I use intel fortran 12.0.3
! ------------------------------------------------- BEGIN
-------------------------------------
module tt
type,public :: aa

contains
final :: aa_final,aa_final_array
end type

type,public :: bb
type(aa),pointer,dimension(:) :: ptr
contains
final :: bb_final,bb_final_array
end type

! -------------- define all the final subroutines
contains
subroutine aa_final(this)
type(aa) :: this
write(*,*) 'aa_final'
end subroutine

subroutine aa_final_array(these)
type(aa),dimension(:) :: these
write(*,*) 'aa_final_array'
end subroutine

subroutine bb_final(this)
type(bb) :: this
write(*,*) 'bb_final'
deallocate(this%ptr)
end subroutine

subroutine bb_final_array(these)
type(bb),dimension(:) :: these
integer :: n,lb,ub

lb = LBOUND(these,1)
ub = UBOUND(these,1)
do n=lb,ub
deallocate(these(n)%ptr)
enddo
write(*,*) 'bb_final_array'

end subroutine

end module

program test
use tt
implicit none
type(bb),pointer,dimension(:) :: barray
type(bb),pointer :: bonly
type(aa),pointer,dimension(:) :: aarray

write(*,*) 'Barray------------'
allocate(barray(2))
allocate(barray(1)%ptr(3))
allocate(barray(2)%ptr(3))
deallocate(barray)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
write(*,*) 'Bonly------------'
allocate(bonly)
allocate(bonly%ptr(2))
deallocate(bonly)
write(*,*) 'Aarray------------'
allocate(aarray(2))
deallocate(aarray)
end
! ------------------------------------------------- END
-------------------------------------

It output:

Barray------------
bb_final_array
Bonly------------
bb_final
aa_final_array
Aarray------------
aa_final_array

We can see that, for Barray, their member ptr are not finalized.
0 Kudos
4 Replies
Steven_L_Intel1
Employee
320 Views
I see that you asked this in comp.lang.fortran and got no answer there yet. I recall that we had a discussion on this general topic with other members of the Fortran standards committee. I will see if I can dig that up.
0 Kudos
jimdempseyatthecove
Honored Contributor III
320 Views
As I see it:

write(*,*) 'Barray------------'
allocate(barray(2))
allocate(barray(1)%ptr(3))
allocate(barray(2)%ptr(3))
deallocate(barray)


The code above is not deallocating: barray(1)%ptr, barray(2)%ptr, ... barray(n)%ptr

Therefore you have a memory leak

Had you declared

type bb
type(aa), allocatable, dimension(:) :: p_a

Then the deallocation (and finalize) would have been automatic on the deletion of the array.

What you did is no different than

subroutine foo
real, pointer, dimension(:) a
allocate(a(1234))
end subroutine foo

The above would create a memory leak because a not deallocated
Whereas:

subroutine fee
real, allocatable, dimension(:)b
allocate(b(1234))
end subroutine fee

causes no memory leak

Steve might be able to dig up the notes on this for the reasoning.

Jim Dempsey


0 Kudos
Hirchert__Kurt_W
New Contributor II
320 Views
As I see it:

write(*,*) 'Barray------------'
allocate(barray(2))
allocate(barray(1)%ptr(3))
allocate(barray(2)%ptr(3))
deallocate(barray)


The code above is not deallocating: barray(1)%ptr, barray(2)%ptr, ... barray(n)%ptr

Therefore you have a memory leak

Jim- Take a look at the OP's definitions of the final procedure for type bb. Both of them contain explicit deallocations of the ptr component, so there should be no memory leak!

If I were the OP, I would add more print statements to the array version of the final procedure, printing out lb and ub before the DO loop, and printing out n inside the DO loop. This would allow me to verify whether that explicit deallocate in the array version is actually being executed. [I don't see any reason why it shouldn't be executed, but I always try to verify these things in case I'm missing something obvious.]

At this point, my guess would be either that something I'm not seeing is messing up the loop, so the deallocate isn't being executed, or there is a compiler bug that is causing it to look for the wrong kind of final procedure for that deallocate. If print statements in the loop produce no output, that would suggest the former; if they do produce output, it would suggest the latter. If it does look like the latter, I would experiment with variations:

a. I would try doing a pointer assignment from these(n)%ptr to a temporary pointer and then do the deallocate on that temporary (in case the fact that these is an array somehow is confusing the compiler).

b. I would try doing a similar DO loop in the main program, to see there is any difference in the behavior.

0 Kudos
jimdempseyatthecove
Honored Contributor III
320 Views
My fault in reading the original post.

RE: insert bounds printout

Good point. If bounds nulled out then the problem be that the array descriptor used by the pointer is cleared prior to final routine call (iow bug)

RE: pointer assignment

The potential problem with this is then you have two pointers referencing the same object. You might also need to insert a NULLIFY of the pointer contained in the array of pointers to tidy up the reference count. As to if this has an effect I cannot say.

Jim Dempsey
0 Kudos
Reply