Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory leaks 派生类型的Fortran数组和内存泄漏(尽管已完成)_Memory Leaks_Fortran_Null Pointer_Derived Types - Fatal编程技术网

Memory leaks 派生类型的Fortran数组和内存泄漏(尽管已完成)

Memory leaks 派生类型的Fortran数组和内存泄漏(尽管已完成),memory-leaks,fortran,null-pointer,derived-types,Memory Leaks,Fortran,Null Pointer,Derived Types,我定义了一个派生类型,并在内存释放方面遇到了一些问题,尽管我已经编写了最后的过程。代码如下 module ModuleCoordinate implicit none type :: TCoordinate real(8),dimension(:),pointer :: Coordinate => NULL() contains procedure :: TCoordinateAssignment generic,public :: Ass

我定义了一个派生类型,并在内存释放方面遇到了一些问题,尽管我已经编写了最后的过程。代码如下

module ModuleCoordinate
  implicit none

  type :: TCoordinate
    real(8),dimension(:),pointer :: Coordinate => NULL()
    contains
      procedure :: TCoordinateAssignment
      generic,public :: Assignment(=) => TCoordinateAssignment
      final :: TCoordinateDel
  end type TCoordinate

  interface TCoordinate
    module procedure :: TCoordinateInit
  end interface TCoordinate

  contains
    subroutine TCoordinateDel(self)
      type(TCoordinate),intent(inout) :: self
      if(associated(self%Coordinate))deallocate(self%Coordinate)
    end subroutine TCoordinateDel

    subroutine TCoordinateAssignment(O1,O2)
      class(TCoordinate),intent(out) :: O1
      type(TCoordinate),intent(in) :: O2
      if(associated(O2%Coordinate))allocate(O1%Coordinate,source=O2%Coordinate)
    end subroutine TCoordinateAssignment

    type(TCoordinate) function TCoordinateInit(IVal1,IVal2) result(self)
      real(8),intent(in) :: IVal1,IVal2
      allocate(self%Coordinate(2))
      self%Coordinate=(/IVal1,IVal2/)
    end function TCoordinateInit
end module ModuleCoordinate
program test
  implicit none
  integer(4),parameter :: NLoop=40000
  integer(4) :: i
  do i=1,NLoop
    call TestMemory1()
    call TestMemory2()
  end do
  pause
end program test

subroutine TestMemory1()
  use ModuleCoordinate
  implicit none
  integer(4),parameter :: DN=10
  integer(4) :: i
  type(TCoordinate),dimension(DN) :: a
  do i=1,DN
    a(i)=TCoordinate(1.0_8,1.0_8)
  end do
end subroutine TestMemory1

subroutine TestMemory2()
  use ModuleCoordinate
  implicit none
  type(TCoordinate) :: b1,b2,b3,b4,b5,b6,b7,b8,b9,b10
  b1=TCoordinate(1.0_8,1.0_8)
  b2=TCoordinate(1.0_8,1.0_8)
  b3=TCoordinate(1.0_8,1.0_8)
  b4=TCoordinate(1.0_8,1.0_8)
  b5=TCoordinate(1.0_8,1.0_8)
  b6=TCoordinate(1.0_8,1.0_8)
  b7=TCoordinate(1.0_8,1.0_8)
  b8=TCoordinate(1.0_8,1.0_8)
  b9=TCoordinate(1.0_8,1.0_8)
  b10=TCoordinate(1.0_8,1.0_8)
end subroutine TestMemory2
测试代码如下所示

module ModuleCoordinate
  implicit none

  type :: TCoordinate
    real(8),dimension(:),pointer :: Coordinate => NULL()
    contains
      procedure :: TCoordinateAssignment
      generic,public :: Assignment(=) => TCoordinateAssignment
      final :: TCoordinateDel
  end type TCoordinate

  interface TCoordinate
    module procedure :: TCoordinateInit
  end interface TCoordinate

  contains
    subroutine TCoordinateDel(self)
      type(TCoordinate),intent(inout) :: self
      if(associated(self%Coordinate))deallocate(self%Coordinate)
    end subroutine TCoordinateDel

    subroutine TCoordinateAssignment(O1,O2)
      class(TCoordinate),intent(out) :: O1
      type(TCoordinate),intent(in) :: O2
      if(associated(O2%Coordinate))allocate(O1%Coordinate,source=O2%Coordinate)
    end subroutine TCoordinateAssignment

    type(TCoordinate) function TCoordinateInit(IVal1,IVal2) result(self)
      real(8),intent(in) :: IVal1,IVal2
      allocate(self%Coordinate(2))
      self%Coordinate=(/IVal1,IVal2/)
    end function TCoordinateInit
end module ModuleCoordinate
program test
  implicit none
  integer(4),parameter :: NLoop=40000
  integer(4) :: i
  do i=1,NLoop
    call TestMemory1()
    call TestMemory2()
  end do
  pause
end program test

subroutine TestMemory1()
  use ModuleCoordinate
  implicit none
  integer(4),parameter :: DN=10
  integer(4) :: i
  type(TCoordinate),dimension(DN) :: a
  do i=1,DN
    a(i)=TCoordinate(1.0_8,1.0_8)
  end do
end subroutine TestMemory1

subroutine TestMemory2()
  use ModuleCoordinate
  implicit none
  type(TCoordinate) :: b1,b2,b3,b4,b5,b6,b7,b8,b9,b10
  b1=TCoordinate(1.0_8,1.0_8)
  b2=TCoordinate(1.0_8,1.0_8)
  b3=TCoordinate(1.0_8,1.0_8)
  b4=TCoordinate(1.0_8,1.0_8)
  b5=TCoordinate(1.0_8,1.0_8)
  b6=TCoordinate(1.0_8,1.0_8)
  b7=TCoordinate(1.0_8,1.0_8)
  b8=TCoordinate(1.0_8,1.0_8)
  b9=TCoordinate(1.0_8,1.0_8)
  b10=TCoordinate(1.0_8,1.0_8)
end subroutine TestMemory2
结果表明,子例程
TestMemory2
正常,而
TestMemory1
不正常,这意味着当声明此派生类型的数组时,最终过程不工作,内存泄漏

但是,如果我在这个派生类型的定义中删除
=>NULL()
坐标右侧的
,这两个子例程似乎都能正常工作

取消分配指针
坐标
时有什么区别?

编者是ifort_2013_sp1.3.174(如果有必要)。

在我们看到的定稿过程描述中(Fortran 2008,4.5.6.2)

如果实体的动态类型有一个最终子例程,其伪参数与最终确定的实体具有相同的种类类型参数和等级,则将实体作为实际参数调用该子例程。否则,如果有一个元素final子例程,其伪参数具有相同的 种类类型参数作为最终确定的实体,将使用实体作为实际参数进行调用。否则,此时不会调用任何子例程

仅为标量(秩-0)实体提供了派生类型的最后一个子例程。要对秩1实体进行终结,最简单的方法(在本例中,似乎是这样)是使您拥有的子例程成为元素

我有点不愿意提及
=>NULL()
方面,因为我目前没有测试我将要编写的内容的方法,但我会猜测

如果没有默认初始化,指针组件将具有未定义的关联状态。这意味着,当你

    b1=TCoordinate(1.0_8,1.0_8)
有趣的事情发生了


作为作业的一部分,
b1
在进入
t协调作业
时完成。终结涉及使用未定义关联状态的指针调用关联的
associated
。这是不允许的(结果可能是任何结果)。

您是否为该类型的数组提供了最终的子例程?不……我只是添加了它,它确实可以工作。谢谢。但是,如果我忘记了数组的最终过程,删除“= > null()”ALSE仍然有点关系。另外,它可能是一个很好的提醒,可以仔细考虑可分配的组件而不是指针。