2014-10-07 74 views
0

當我通過任gfortran和Valgrind的或ifort和Intel檢查運行下面的代碼檢測到所述第一時間的步驟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

第一次組結合被稱爲你分配一個「匿名」大小的3數組來存儲所提供的整數。同時,您將intArray組件關聯到指向新分配的數組 - 當您指定ALLOCATE指針時,語句在概念上做兩件事。

第二次調用set綁定時,在重複指針分配過程之前,打破intArray組件與帶有NULLIFY語句的分配之間的關聯。

廢除不(一定)解除分配。你的程序已經基本上失去了三號陣列初始分配的軌道。三個整數,通常每個整數四個字節 - 丟失十二個字節。

如果使用指針,一個總的原則是,對於每一個在你的代碼路徑ALLOCATE遇到你需要在後面的代碼路徑匹配DEALLOCATE。 (在Fortran 2003或更高版本中(這就是你使用的,因爲你有類型綁定的過程),如果你真的指向它們,你應該只使用指針和指針組件,如果你真的只是使用指針和指針組件指針爲「值」,那麼你就應該使用分配變量或組件)。

1

泄漏實際情況對set第二個呼叫。您nullify指針,但它已經關聯,並且內容丟失。因此,您必須先撥打deallocate,然後使用associated()測試關聯狀態。