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