2011-01-10 27 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的后期版本中可用,但默认情况下不处于活动状态。查看上面的最后一个链接。