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=5およびhttp://software.intel.com/en-us/blogs/2008/03/31/doctorの議論も参照してください。 -これをやると痛い/ .

Fortran 2003 の別の新機能を実装すると、"real :: array(5,5)" を "array" を割り当て可能として宣言するように変更できるようになり、割り当て時に正しいサイズに自動的に割り当てられます --事前に割り当てる必要はありません。非常に簡単!これはインテル Fortran の最新バージョンで使用できますが、デフォルトではアクティブではありません。上記の最後のリンクを参照してください。

于 2011-01-10T16:59:04.887 に答える
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)

おそらくすぐに、はるかに優れた専門知識を持つ誰かが返信するでしょう。とりあえずこれでいいと思います。

于 2011-01-10T16:07:12.670 に答える