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中测试内存泄漏(使用pFUnit)_Memory Leaks_Fortran_Gfortran - Fatal编程技术网

Memory leaks 在Fortran中测试内存泄漏(使用pFUnit)

Memory leaks 在Fortran中测试内存泄漏(使用pFUnit),memory-leaks,fortran,gfortran,Memory Leaks,Fortran,Gfortran,我已经用allocatable编写了我的第一个程序。它按预期工作。但是,真的吗?更重要的是,我如何设置一个单元测试来捕获内存泄漏 这个计划的想法是首先为我的物品清单分配一个储藏室。每次我在列表中添加一个比分配的大小多的元素时,我会加倍分配。我这样做是为了减少从旧分配内存到新分配内存的分配和后续数据复制的数量 我可能会把这件事复杂化,但我现在想花一些时间来理解其中的陷阱,而不是在项目的一两年中首先陷入陷阱 ode是在linux上使用gfortran 8.3.0编译的。以及使用PF4.1单元。下面的

我已经用allocatable编写了我的第一个程序。它按预期工作。但是,真的吗?更重要的是,我如何设置一个单元测试来捕获内存泄漏

这个计划的想法是首先为我的物品清单分配一个储藏室。每次我在列表中添加一个比分配的大小多的元素时,我会加倍分配。我这样做是为了减少从旧分配内存到新分配内存的分配和后续数据复制的数量

我可能会把这件事复杂化,但我现在想花一些时间来理解其中的陷阱,而不是在项目的一两年中首先陷入陷阱

ode是在linux上使用gfortran 8.3.0编译的。以及使用PF4.1单元。下面的代码是仅测试分配部分的摘录

这是我的测试计划:

  program test_realloc
    use class_test_malloc
    integer :: i
    real :: x, y
    type(tmalloc) :: myobject


    call myobject%initialize()

    do i=1, 100
      x = i * i
      y = sqrt(x)
      call myobject%add_nbcell(i, x, y)
    end do

    call myobject%dump()

end program test_realloc
数组_重新分配。f:

        !
    ! Simple test to see if my understanding of dynamicly allocation
    ! of arrays is correct.
    !

    module class_test_malloc
       use testinglistobj
       implicit none

  type tmalloc
      integer :: numnbcells, maxnbcells
      type(listobj), allocatable :: nbcells(:)
  contains

      procedure, public :: initialize => init
      procedure, public :: add_nbcell    ! Might be private?
      procedure, private :: expand_nbcells
      procedure, public :: dump

  end type tmalloc

  contains

    subroutine init(this)
      class(tmalloc), intent(inout) :: this

      this%numnbcells = 0
      this%maxnbcells = 4
      allocate (this%nbcells(this%maxnbcells))
    end subroutine init


    subroutine add_nbcell(this, idx, x, y)
      class(tmalloc), intent(inout) :: this
      integer, intent(in) :: idx
      real, intent(in) :: x, y
      type(listobj) :: nbcell

      if(this%numnbcells .eq. this%maxnbcells) then
        call this%expand_nbcells()
        print *,"Expanding"
      endif

      this%numnbcells = this%numnbcells + 1
      nbcell%idx = idx
      nbcell%x = x
      nbcell%y = y
      this%nbcells(this%numnbcells) = nbcell
      print *,"Adding"
    end subroutine add_nbcell

    subroutine expand_nbcells(this)
      class(tmalloc), intent(inout) :: this
      type(listobj), allocatable :: tmpnbcells(:)
      integer :: size

      size = this%maxnbcells *2
      allocate (tmpnbcells(size))
      tmpnbcells(1:this%maxnbcells) = this%nbcells
      call move_alloc( from=tmpnbcells, to=this%nbcells)
      this%maxnbcells = size
    end subroutine

    subroutine dump(this)
      class(tmalloc), intent(inout) :: this
      integer :: i

      do i=1, this%numnbcells
        print*, this%nbcells(i)%x, this%nbcells(i)%y
      end do
    end subroutine

  end module
listobj.f:

  module testinglistobj
  type listobj
       integer :: idx
       real :: x
       real :: y
  end type
  end module testinglistobj

此代码不会导致任何内存泄漏。原因是,这是理解可分配数组的基础,在Fortran 95以后的版本中,要求不带save属性的可分配数组在超出范围时自动取消分配。这样做的净结果是这样的阵列不可能出现内存泄漏。这就是为什么您更喜欢可分配数组而不是指针的一个很好的原因。相关的是一般的软件工程原理,即尽可能限制变量的范围,以便数组在内存中的时间尽可能短


请注意,这并不意味着您永远不应该取消分配它们,因为数组可能在实际使用后很长时间仍保留在作用域中。在这里,可以使用手动解除分配。但这不是内存泄漏。

一般来说,如果您使用的是可分配对象,并且存在内存泄漏,那是编译器编写者的错,而不是您的错。原则上没有问题。你有具体的理由担心吗?如果是这样,有一些工具可以提供帮助[首先,gfortran的-Wall和-fcheck=all标志,后者不适用于生产运行,因为它支持运行时检查,valgrind也可能有帮助]。有什么理由提到PFU吗?