- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
![](/skins/images/7FC17B7B85029576C25F1E43CE255B51/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page