функция, возвращающая массив без определенной явной формы - PullRequest
1 голос
/ 10 января 2011

Мне интересно, как вернуть массив из функции без знания формы до времени выполнения (включая предполагаемые массивы формы).Я объясню с примерами.Это работает

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

Как насчет этого?это действительно Фортран?у меня утечка памяти в этом случае

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 ]

3 голосов
/ 10 января 2011

Эта способность функции возвращать размещаемый массив обеспечивается 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-it-hurts-when-i-do-this/.

Еще одна новая функция Fortran 2003, когда она будет реализована, позволит вам заменить «real :: array (5,5)» на объявление «массива» как выделяемого, и он будет автоматически назначен на правильный размер при назначение - нет необходимости предварительно выделять его. Очень просто! Это доступно в последних версиях Intel Fortran, но по умолчанию не активно. См. Последнюю ссылку выше.

2 голосов
/ 10 января 2011

Если я скомпилирую этот код:

(файл 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)

Возможно, скоро кто-то с гораздо большим опытом ответит;Надеюсь, это пока подойдет.

...