Вызовы подпрограмм с размещаемыми массивами

В моем коде у меня проблемы с памятью из-за компьютера, который я использую, поэтому я хочу выделить как можно меньше памяти при передаче аргументов. Мой пример кода:

program test
double precision, ALLOCATABLE :: arrayA(:)
allocate (arrayA(n))

call mySub (arrayA)

deallocate (arrayA)

stop
end

subroutine mySub ( arrayB )
double precision, ALLOCATABLE :: arrayB(:)

allocate (arrayB(n))
! operations with arrayB

return
end

В основной программе я должен использовать кучу памяти. Я также хочу использовать кучу памяти в моей субтренировке. В соответствии с поиском, который я сделал, он дает ошибку при выполнении (Попытка выделить уже выделенный массив 'arrayb').

Поэтому мои цели состоят в том, чтобы использовать память кучи также в моих подпрограммах и выделить как можно меньше памяти при передаче аргументов из программы в подпрограмму, как в коде выше. Теперь, я думаю, что я делаю копию задания, и, как я знаю, это не хорошо. Я проверил модуль, интерфейс и содержит блоки, но не очень понятно, какой из них хорош для экономии места в памяти с помощью массивов allocatabel. Я ценю любую помощь, вписывающуюся в мои цели.

2 ответа

Вы не можете выделить массив снова, когда он уже выделен. В этом тоже нет смысла. Кроме того, размещаемые фиктивные аргументы требуют явного интерфейса с использованием модулей или аналогичных. Но кто знает, как выглядит ваш настоящий код?

То, что вы хотите, это просто передать его простым способом, как у вас было изначально

subroutine mySub ( arrayB, n )
  integer :: n
  double precision :: arrayB(n)

! operations with arrayB

Это просто отлично. Никакая копия не будет сделана, если вы передадите непрерывный массив в том виде, в котором он показан Читайте про прохождение по ссылке. В чем разница между передачей по ссылке и передачей по значению?

Вы также можете использовать предполагаемые массивы форм (:), но будьте осторожны, вам нужен явный интерфейс (лучше всего использовать модули).

Если процедура имеет фиктивный аргумент, то есть размещаемый, то явный интерфейс требуется в любой вызывающей области. Вы можете предоставить этот явный интерфейс, поместив блок интерфейса для своей подпрограммы внутри основной программы. Лучшая альтернатива - поместить подпрограмму в модуль и ИСПОЛЬЗОВАТЬ этот модуль в основной программе. Затем автоматически создается явный интерфейс.

В Fortran (по крайней мере, в Fortran 90 или более ранних версиях) невозможно выделить массив с помощью подпрограммы и вернуть выделенный массив основной программе. В вашем случае вы не должны размещать массив в подпрограмме. Таким образом, ваша подпрограмма может быть:

subroutine mySub ( arrayB )

double precision :: arrayB(:)

! operations with arrayB

return
end

Затем вы можете передать любой массив, имеющий тот же ранг, что и arrayB, но фактический аргумент должен быть уже размещен в main, как вы это и сделали.

     program test

double precision, ALLOCATABLE :: arrayA(:)

allocate (arrayA(n))

call mySub (arrayA)

deallocate (arrayA)

stop
end
Другие вопросы по тегам