内存泄漏与派生类型指针

时间:2014-10-07 20:04:32

标签: memory-leaks fortran

当我通过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)

有关行号,请参阅代码中的注释。

2 个答案:

答案 0 :(得分:3)

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

第二次调用set绑定时,在重复指针分配过程之前,先断开intArray组件与NULLIFY语句分配之间的关联。

Nullify不(必然)解除分配。你的程序基本上没有跟踪三级数组的初始分配。三个整数,通常每个整数四个字节 - 丢失十二个字节。

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

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

答案 1 :(得分:2)

泄漏实际上发生在set的第二次调用上。您nullify指针,但它已经关联,内容丢失。因此,您必须先调用deallocate并使用associated()测试关联状态。