在Fortran中正确执行Final例程 [英] Correct execution of Final routine in Fortran

查看:186
本文介绍了在Fortran中正确执行Final例程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下Fortran代码

I have following Fortran code

  type t_octree
     integer                        :: max_num_point
     class(t_octree_node), pointer  :: root => null()
     contains
     final                         :: DESTROY_OCTREE
  end type t_octree

  type t_octree_node
     real                          :: box(2,3)
     integer                       :: depth
     type(t_octree_node), pointer  :: parent      => null()
     type(t_octree_node), pointer  :: children(:) => null()
     class(t_octree_leaf), pointer :: leaf        => null()
  contains
     final                         :: CLEAN_NODE
  end type t_octree_node
  type, extends(t_octree_node) :: t_octree_leaf
     integer, allocatable          :: id(:)
     integer                       :: num_point
  contains
     final                          :: DESTROY_LEAF
  end type

在完成处理后,现在需要确保正确地释放了我的东西.

After I have done my processing and now need to make sure that my stuff is deallocated properly.

在我的最终程序中,

  subroutine DESTROY_OCTREE( this )

  implicit none

  type(t_octree)               :: this
  type(t_octree_node), pointer :: node => null()
  integer                      :: i


  node => this% root
  if( associated(node% leaf) )deallocate( node% leaf )

  if(.not. associated(node% children) )RETURN
  deallocate(  node )
  node => this% root
  i = 0
  nullify(node)
  print*, associated(this% root) ! this is true!! 
  print*, associated(this% root% children) ! this is true!! 



  end subroutine DESTROY_OCTREE

  recursive subroutine CLEAN_NODE ( this )

  implicit none

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

  if( associated(this% leaf) )then
     deallocate( this% leaf )
     nullify( this% leaf )
  endif
  if(.not. associated(this% children) )RETURN
  do i = 1, 8
     node => this% children(i)
     deallocate( node )
     nullify(node)
    ! debug
    ! print*, i, "rec"
  enddo
   nullify(this% children)
   nullify(this% parent)

  end subroutine CLEAN_NODE

  subroutine DESTROY_LEAF ( leaf )

  implicit none

  type(t_octree_leaf)        :: leaf

  deallocate( leaf% id )

  end subroutine DESTROY_LEAF

在我的主程序中,我确实关注

In my main program I do following

  program TEST_OCTREE
  use MD_OCTREE

  implicit none

  type(t_octree), pointer               :: octree

  octree      => t_octree( max_num_point,  box )
  (...) ! all processing to build the data structure

现在我可以通过简单地取消分配

Now I deallocate by simply

  deallocate( octree )  
  print*, associated(octree% root) ! this give a segmentation fault

问题 有人可以解释为什么我的print*, associated(this% root)命令仍然显示TRUE的原因,而在主程序中打印时却好像已经被重新分配了,因为它给了我分段错误

The question Can somebody explain why it seems that my print*, associated(this% root) commands still show TRUE while when printing in my main program it looks like it has been deallocated as it gives me a segmentation fault

推荐答案

取消分配指针会导致与同一目标关联的任何其他指针的指针关联状态变为未定义(F2018 9.7.3.3p2).这种情况发生在DESTROY_OCTREE过程中的nodethis%root上-两个指针都引用同一个对象(通过指针分配node => this% root,该对象通过node指针被释放-这使得this%root具有未定义的关联状态.

Deallocating a pointer causes the pointer association status of any other pointer that was associated with the same target to become undefined (F2018 9.7.3.3p2). This situation happens with node and this%root in the DESTROY_OCTREE procedure - both pointers reference the same object (via the pointer assignment node => this% root, the object is deallocated through the node pointer - which makes this%root have undefined association status.

ASSOCIATED内部函数的参数不得为具有未定义关联状态的指针(F2018 16.9.16p3).该代码不符合规范,可能会发生任何事情-任何事情"都可以合理地包含您看到的结果.

The argument to the ASSOCIATED intrinsic must not be a pointer with undefined association status (F2018 16.9.16p3). The code is non-conforming, anything may happen - where "anything" quite reasonably includes the results you see.

通过node指针释放对象时,没有简单的方法可以使处理器可靠地更新this%root指针的状态-它最终指向不再存在的对象.

When you deallocate the object through the node pointer, there is no simple way that the processor can also reliably update the status of the this%root pointer - it ends up pointing at something that no longer exists.

所示的源代码片段中还有其他可疑的构造,包括在同一指针对象上执行DEALLOCATE语句后使用多余的NULLIFY(成功的释放会取消关联(使指针无效)),在可能合适的DEALLOCATE时使用nullify(没有完整的代码很难说),并使用似乎是结构构造函数的指针目标.

There are other suspicious constructs in the fragments of source shown, including use of a superfluous NULLIFY after a DEALLOCATE statement on the same pointer object (successful deallocation disassociates (nullifies) the pointer), use of nullify when perhaps DEALLOCATE is appropriate (hard to say without complete code), and use of what appears to be a structure constructor as a pointer target.

这篇关于在Fortran中正确执行Final例程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆