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
4

2 回答 2

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”声明为可分配对象,并且在分配时它会自动分配到正确的大小——无需预先分配。很容易!这在 Intel Fortran 的最新版本中可用,但默认情况下不活动。请参阅上面的最后一个链接。

于 2011-01-10T16:59:04.887 回答
2

如果我编译这段代码:

(文件栏.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)

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

于 2011-01-10T16:07:12.670 回答