【问题标题】:Memory leak with derived type pointer派生类型指针的内存泄漏
【发布时间】:2014-10-08 04:43:50
【问题描述】:

当我通过 gfortran 和 Valgrind 或 ifort 和 Intel Inspector 运行以下代码时,第一次为对象调用过程 set 时检测到内存泄漏。不过,第二次似乎不会导致任何内存泄漏。这是为什么呢?

module mymod
    implicit none

    type mytype
        integer, pointer :: intArray(:) => null()
    contains
        procedure :: set
    end type mytype

contains

    subroutine set(this, intArray)
        class(mytype), intent(inout) :: this
        integer, intent(in) :: intArray(:)
        integer n

        n = size(intArray)

        nullify(this%intArray)
        allocate(this%intArray(n)) !line 20
        this%intArray = intArray

    end subroutine set

end module mymod

program main
    use mymod !line 28
    implicit none

    type(mytype) :: myvar

    call myvar%set((/1,2,3/)) !line 33
    print *, myvar%intArray
    call myvar%set((/9,8,7,6,5/))
    print *, myvar%intArray

end program main

Valgrind 报告以下内存泄漏:

==6669== 12 bytes in 1 blocks are definitely lost in loss record 1 of 2
==6669==    at 0x402BB7A: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==6669==    by 0x804886A: __mymod_MOD_set (main.f90:20)
==6669==    by 0x8048988: MAIN__ (main.f90:33)
==6669==    by 0x8048ADC: main (main.f90:28)

行号见代码中的cmets。

【问题讨论】:

    标签: memory-leaks fortran


    【解决方案1】:

    第一次调用 set 绑定时,您分配一个“匿名”大小为 3 的数组来存储提供的整数。同时,您将 intArray 组件关联到指向新分配的数组 - 当您分配指针时,该语句在概念上做了两件事。

    第二次调用 set 绑定时,在重复指针分配过程之前,您会使用 NULLIFY 语句破坏 intArray 组件和分配之间的关联。

    Nullify 不会(必然)解除分配。您的程序基本上已经忘记了大小为 3 的数组的初始分配。三个整数,通常每个整数四个字节 -- 丢失十二个字节。

    如果您使用指针,一般原则是,对于代码路径中遇到的每个 ALLOCATE,您需要在后面的代码路径中具有匹配的 DEALLOCATE。

    (在 Fortran 2003 或更高版本中(这是您正在使用的,因为您有类型绑定过程),您应该只使用指针和指针组件,如果您实际将它们指向事物。如果您真的只是使用指针作为“值”,那么您应该使用可分配的变量或组件。)

    【讨论】:

      【解决方案2】:

      泄漏实际上发生在set 的第二次调用中。你nullify指针,但是已经关联了,内容丢失了。所以,你必须先调用deallocate,并测试与associated()的关联状态。

      【讨论】:

        猜你喜欢
        • 2014-05-10
        • 1970-01-01
        • 2011-07-08
        • 1970-01-01
        • 2010-12-29
        • 2013-11-30
        • 1970-01-01
        • 1970-01-01
        • 2022-01-26
        相关资源
        最近更新 更多