Quantcast
Channel: Intel® Fortran Compiler for Linux* and macOS*
Viewing all articles
Browse latest Browse all 2583

Finalization is not deallocating everything as intended

$
0
0

Hello there,

I have tried for sometime to analyze what's going on regarding my finalization subroutine - with no luck. Let me start showing the bit of the code you need to understand what I am trying to and hopefully spot my bug. So firstly here are my declared types, (i have made them a bit simpler just to illustrate the point)

 

      type root_node
         type(nodes), pointer   :: root => null()
         contains
         final                          :: DESTROY_ROOT
      end type root_node

      type nodes
         type(nodes), pointer  :: parent      => null()
         type(nodes), pointer  :: children(:) => null()
         type(nodes), pointer  :: leaf        => null()
      contains
         final                         :: DESTROY_node
      end type nodes

      type leaf
         integer, allocatable          :: id(:)
         integer                       :: num_point
      contains
         final                         :: DESTROY_LEAF
      end type leaf

 

 

Now I will show the the three final routines, the main is DESTROY_ROOT which will be calling the other two, and eventually destroy everything.

 

 

      subroutine DESTROY_ROOT( this )

      implicit none

      type(ROOT)               :: this
      integer                      :: i

      if(.not. associated(this% root% children) )RETURN
      deallocate(  this% root )


      end subroutine DESTROY_ROOT

      recursive subroutine DESTROY_NODE ( this )

      implicit none

      type(t_octree_node)           :: this
      type(t_octree_node), pointer  :: node => null(), next => null()
      integer                       :: i
      integer, save ::debug=0


      if( associated(this% leaf) )then
         deallocate( this% leaf )
         nullify(this% parent)
         RETURN
      endif

      do i = 1, 8
         node => this% children(i)
         debug = debug + 1
         print*, i, debug
         deallocate( node )
      enddo
      nullify( this% children )
     ! deallocate(node%children) commented as it does not work  - crashes!
     end subroutine DESTROY_NODE


      subroutine DESTROY_LEAF ( leaf )

      implicit none

      type(LEAF)        :: leaf
      deallocate( leaf% id )

      end subroutine DESTROY_LEAF

 

 

When I use my monitoring tool on my laptop to check the memory consumption it is observed that the memory declines when the deallocation process begins, however, it seems like a lot is still left without being cleared. I tried to compare this to a normal subroutine which clears the memory and it was clear that the entire memory allocated was being freed again.  The only difference with those two example were that the leaf type was not considered, instead all children had a "id" allocatable. So that clearing is basically done by 

 

 

  recursive subroutine DESTROY_NODE2(node)

    type(node_type), intent(inout) :: node

    integer i

    if (associated(node%children)) then
      do i = 1, 8
        call clean_node(node%children(i))
        deallocate(node%children(i)%id)
      end do
      deallocate(node%children)
    end if

  end subroutine DESTROY_NODE2

 

As you observe there is an deallocate(node%children), which does not work if I place it my DESTROY_NODE routine. Note again that DESTROY_NODE2 is not a final routine, but just a normal routine called by  " call DESTROY_NODE2 ( node )". 

 

 

Does anybody see what I am doing wrong please?

 

Happy new year !!

 

 


Viewing all articles
Browse latest Browse all 2583

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>