Динамические (распределяемые) массивы

Обычно переменные описываются в начале программы (модуля). При этом компилятор заранее выделят память для размещения этих переменных. Такие переменные называются статическими. Статический массив объявляется также в начале программы. Занимаемая ими память не меняется до завершения программы.

Иногда возникает необходимость выделять память под переменные в процессе работы программы, например, когда:

В этих случаях на помощь приходит динамическое выделение памяти. В Fortrane-е для этого появились Динамические массивы.

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

Например, программе потребуется выполнять операции с массивом, в котором хранятся оценки студентов после сессии. Но программист, когда пишет программу, не знает, сколько будет студентов.

Тогда описывается динамический массив Mark:

implicit none
integer, allocatable :: Mark(:)
integer N_students,val
...

Определяется требуемый размер массива:
read *, N_students

Выделяется память под массив:
allocate(Mark(N_students),stat=val)
...
Когда он становится ненужным, необходимо освободить память:
deallocate(Mark)

Аналогично для 2-ух мерного массива:

implicit none
integer, allocatable :: GrpMarks(:,:)
integer N_students,n_grp,val
...

read *, n_grp,N_students
allocate(GrpMarks(n_grp,N_students),stat=val)
...
deallocate(GrpMarks)

 

Спецификация

Распределяемые массивы декларируются так же как статические. Общий вид таков:
type, ALLOCATABLE [,атрибут ] :: name
Они должны включать атрибут ALLOCATABLE и ранг массива, но не могут специфицировать протяженность ни в каком измерении. Вместо этого используется двоенточие (:) для кажого измерения. Например:

INTEGER, DIMENSION(:), ALLOCATABLE :: a   ! ранг 1
INTEGER, ALLOCATABLE :: b(:,:)   !ранг  2
REAL, DIMENSION(:), ALLOCATABLE :: c   ! ранг1

После декларации распределяемые массивы не имеют соответствующей памяти и на них нельзя ссылаться, пока не будет явно выделена память.

Выделение и возвращение памяти

Оператор ALLOCATE динамически выделяет требуемое количество памяти и связывает ее с распределяемым массивом.
ALLOCATE( имя(границы) [,STAT] )

С помощью одного оператора ALLOCATE можно распределить несколько массивов - каждый с различными границами, образом или рангом. Если не специфицирована меньшая граница, она полагается равной 1. Только распределяемый массив с неопределенной для него памятью может быть объектом оператора ALLOCATE:

  n=10
  ALLOCATE( a(100) )
  ALLOCATE( b(n,n), c(-10:89) )

Память, использованная распределяемым массивом, должно быть освобождено (когда он перестал быть нужен) с помощью оператора DEALLOCATE:
DEALLOCATE( имя_массива [,STAT] )

Оператор DEALLOCATE позволяет освободить несколько массивов.
Следующие операторы освобождают память из предыдущего примера:

DEALLOCATE ( a, b )
DEALLOCATE ( c, STAT=test )
IF (test .NE. 0) THEN
     STOP ' ошибка возвращения '
ENDIF

Хорошей практикой программирования считается возвращение любой памяти, которая была зарезервирована с помощью оператора ALLOCATE .
Остерегайтесь: учтите, что любые данные, сохраненные в памяти динамического массива, недоступны после ее освождения!

Статус распределяемых массивов

Распределяемые массивы могут быть в одном из двух статусов (состояний):

Статус массива может быть проверен с помощью встроенной логической функции ALLOCATED:

   AllOCATED( имя )

которая возвращает значение:

Например:

   IF( ALLOCATED(x) ) DEALLOCATE( x )

или:

   IF( .NOT. ALLOCATED( x ) ) ALLOCATE( x(1:10) )

После декларации статус распределяемого массива будет иметь значение 'не распределен в данный момент' и получит значение 'распределен' только после того, как успешно будет выполнен оператор ALLOCATE. Когда программа продолжится и память, использованная конкретным массивом, будет возвращена, статус массива вернется к значению 'не распределен в данный момент '. Возможно повторять этот цикл распределения и возвращения памяти массиву (возможно с различным размером и протяженностью каждый раз) любое число раз в одной и той же программе.

 

 

Hosted by uCoz