2011-01-10 51 views
1

我想知道如何從函數返回一個數組,直到運行時(包括假定的形狀數組)。我會用例子來解釋。這工作函數返回沒有定義顯式形狀的數組

module foo 
contains 
    function getArray(:) 
     real :: getArray(3) 
     integer :: i 
     do i=1,3 
     getArray(i) = 10.0*i 
     enddo 
    end function 

end module 

program xx 
    use foo 
    real :: array(3) 
    integer :: i 

    array = getArray() 
    print *, array 
end program 

這也適用,因爲它使用自動數組

module foo 
contains 
    function getArray(length) 
     integer :: length 
     real :: getArray(length) 
     integer :: i 
     do i=1,length 
     getArray(i) = 10.0*i 
     enddo 
    end function 

end module 

program xx 
    use foo 
    real :: array(5) 
    integer :: i 

    array = getArray(5) 
    print *, array 
end program 

這個怎麼樣的? Fortran有效嗎?我有內存泄漏在這種情況下

module foo 
    contains 
    function getArray() 
     real, allocatable :: getArray(:) 
     integer :: length 
     integer :: i 

     length = 5 ! coming, for example, from disk 

     allocate(getArray(length)) 

     do i=1,length 
      getArray(i) = 10.0*i 
     enddo 

     ! cannot call deallocate() or a crash occurs 
    end function 

end module 

use foo 
    real :: array(5,5) ! get max size from other means, so to have enough space 
    integer :: i 

    array = getArray() 
    ! leaking memory here ? unexpected behavior ? 
end program 
+0

在你的最後一個例子中,getArray有兩個維度,但你將它視爲一維數組。這是爲什麼? – canavanin 2011-01-10 15:24:57

回答

2

如果我編譯此代碼:

(文件bar.f90)

program bar 

    use foo 

    real :: array(5,5) ! get max size from other means, so to have enough space 
    integer :: i 

    array = getArray() 
    ! leaking memory here ? unexpected behavior ? 

end program 

(文件foo.f90)

module foo 
    contains 
    function getArray() 
     real, allocatable :: getArray(:,:) 
     integer :: length 
     integer :: i 

     length = 5 ! coming, for example, from disk 

     allocate(getArray(length,length)) 

     do i=1,length 
      getArray(i,:) = 10.0*i 
     enddo 

     ! cannot call deallocate() or a crash occurs 
    end function 

end module 

使用ifort -debug foo.f90 bar.f90

讓Valgrind的檢查可執行一切似乎很動聽:

valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 ./a.out 
==8019== Memcheck, a memory error detector 
==8019== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
==8019== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info 
==8019== Command: ./a.out 
==8019== 
==8019== 
==8019== HEAP SUMMARY: 
==8019==  in use at exit: 0 bytes in 0 blocks 
==8019== total heap usage: 2 allocs, 2 frees, 108 bytes allocated 
==8019== 
==8019== All heap blocks were freed -- no leaks are possible 
==8019== 
==8019== For counts of detected and suppressed errors, rerun with: -v 
==8019== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6) 

可能很快有人用更大的專業知識,將回復;我希望這會暫時做。

3

TR 15581提供了此函數返回可分配數組的能力。請參見http://www.nag.co.uk/nagware/np/doc/tr.asp。該函數必須分配數組,並且「可分配數組函數的結果在被使用後自動釋放」,即沒有內存泄漏!

另請參閱http://www.tek-tips.com/viewthread.cfm?qid=1613318&page=5http://software.intel.com/en-us/blogs/2008/03/31/doctor-it-hurts-when-i-do-this/的討論。

Fortran 2003的另一個新特性實現時,可以讓你改變「real :: array(5,5)」來聲明「array」也是可分配的,並且它會被自動分配到正確的大小分配後 - 無需預先分配。好簡單!這在英特爾Fortran的後期版本中可用,但默認情況下不處於活動狀態。查看上面的最後一個鏈接。