函数返回数组没有明确的显式形状

时间:2011-01-10 14:25:13

标签: arrays function fortran fortran90

我想知道如何在不知道形状的情况下从函数返回一个数组,直到运行时(包括假定的形状数组)。我将用例子来解释。这工作

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

2 个答案:

答案 0 :(得分: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的后期版本中可用,但默认情况下不活动。见上面的最后一个链接。

答案 1 :(得分:2)

如果我编译这段代码:

(file 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

(file 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)

可能很快就会有更多专业知识的人回复;我希望暂时这样做。