Memory leaks 具有派生类型指针的内存泄漏

Memory leaks 具有派生类型指针的内存泄漏,memory-leaks,fortran,Memory Leaks,Fortran,当我通过gfortran和Valgrind或ifort和Intel Inspector运行下面的代码时,在第一次为对象调用过程set时会检测到内存泄漏。第二次似乎不会导致任何内存泄漏。为什么呢 module mymod implicit none type mytype integer, pointer :: intArray(:) => null() contains procedure :: set end type m

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

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

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

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

Nullify(不一定)取消分配。您的程序基本上已经无法跟踪大小为3的阵列的初始分配。三个整数,通常每个整数四个字节——丢失十二个字节

如果使用指针,一般原则是,对于代码路径中遇到的每个分配,需要在后面的代码路径中进行匹配的释放


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

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

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

Nullify(不一定)取消分配。您的程序基本上已经无法跟踪大小为3的阵列的初始分配。三个整数,通常每个整数四个字节——丢失十二个字节

如果使用指针,一般原则是,对于代码路径中遇到的每个分配,需要在后面的代码路径中进行匹配的释放


(在Fortran 2003或更高版本中(这是您正在使用的,因为您有类型绑定的过程),只有当您实际将指针和指针组件指向对象时,才应该使用它们。如果您实际上只是将指针用作“值”,则应使用可分配变量或组件。)泄漏实际上发生在第二次调用
set
时。您可以将指针设为空,但指针已关联且内容丢失。因此,您必须在调用之前调用
deallocate
,并使用
associated()
测试关联状态泄漏实际上发生在第二次调用
set
时。您可以将指针设为空,但指针已关联且内容丢失。因此,您必须在之前调用
deallocate
,并使用
associated()
测试关联状态