Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Fortran 90. ANSI Standard.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
861.18 Кб
Скачать

Динамическая память

Как указание на существующие переменные, которые имеют атрибут TARGET , так и указатели могут быть связаны с блоками динамической памяти. Эта память связывается с помощью оператора ALLOCATE, который создает неименованную переменную или массив указанного размера, и с типом данных, рангом и т.п. указателя:

REAL, POINTER :: p, pa(:)

INTEGER :: n=100

...

ALLOCATE( p, pa(n) )

...

DEALLOCATE( p, pa )

В приведенном примере p указывает на область динамической памяти и может владеть одним числом типа real , а pa указывет на блок динамической памяти из 100 чисел типа real. Когда память боль не нужна, она может быть возвращена (освобождена) с помощью оператора DEALLOCATE . В этом отношении указатели имеют много похожего с выделяемыми массивами.

Я

Общие ошибки

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

  • память становится известной и возникать из выделения динамической памяти указателю и когда переприсваивается указатель другому адресату:

INTEGER, POINTER :: pt(:)

...

ALLOCATE( pt(25) )

NULLIFY( pt ) ! неправильно

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

  • Возможно присваивать указателю адресат, но когда перемещается адресат (при освобождении памяти или выходе процедуры , к нему локальной), в этом случае указатель может быть слева "болтающимся":

REAL, POINTER :: p1, p2

...

ALLOCATE( p1 )

p2 => p1

DEALLOCATE( p1 ) ! неверно

В приведенном примере p2 указывает на память, связанную с p1. Не смотря на это когда память освобождена p2 no longer имеет верный адресат и получает свой статус неопределенным. В этом случае разыменование p2 приведет к непредсказуемому результату.

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

 Я

Array Pointers

Указатели могут вести себя как динамические псевдонимы для массивов и секций массивов. Такие указатели называют указателями массива. Указатели массива можно использовать, когда секция ссылается часто и может сохранять копию данных. Например:

REAL, TARGET :: grid(10,10)

REAL, POINTER :: centre(:,:), row(:)

...

centre => grid(4:7,4:7)

row => grid(9,:)

Указатель массива может быть связан со всем массивом или выбранной частью. Размер и протяженность массива можно изменить так, как требуется даже с рапределяемыми массивами. Например:

centre => grid(5:5,5:6) ! внутренние 4 элемента от прежней середины

Заметим, что указатель массива не нужно возвращать прежде чем переопределены его протяженность или границы.

INTEGER, TARGET :: list(-5:5)

INTEGER, POINTER :: pt(:)

INTEGER, DIMENSION(3) :: v = (/-1,4,-2/)

...

pt => list ! указывает границы для pt

pt => list(:) ! указывает границы для pt

pt => list(1:5:2)

pt => list( v ) ! неверно

  

Протяженность (или границы) секции массива определяются типом присваивания, использованным для присваивания указателя. Когда указатель массива определяется массивом, соответствующий указатель массива принимает вид его расширения к массиву-адресату как это было выше с pt => list , оба имеют границы -5:5. Если указатель массива связывается с секцией массива (даже если секция равна всему массив у), его меньшая граница в каждом измерении равна 1 - как с pt => list(:) выше, протяженость pt равна 1:11, тогда как протяженность для list равна -5:5. Так pt(1) привязан к list(-5), pt(2) к list(-4), и т.д.

Возможно связать указатель массива с секцией массива, определенной с помощью тройки выписки. Невозможно связать один с секцией массива , определенной выпиской вектора , выше v . Присваивание уазателя pt => list(1:5:2) верно с pt(1), связанным с list(1), pt(2), связанным с list(3) и pt(3) ), связанным с list(5).

 Я

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]