Атрибут указателя Фортрана на объявления типов - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть следующий тип

  type OCTREE_TYPE
     real                          :: box(2,3)
     integer, allocatable          :: icells(:)
     integer                       :: num_point
     integer                       :: depth
     type(OCTREE_TYPE), pointer    :: parent      => NULL()
     type(OCTREE_TYPE), pointer    :: children(:) => NULL()
  end type OCTREE_TYPE

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

   type(OCTREE_TYPE),pointer        :: octree_node

и это

  type(OCTREE_TYPE)        :: octree_node

кроме того, что один из них является указателем, а другой - нет.

1 Ответ

0 голосов
/ 14 декабря 2018

в чем разница (...), кроме того, что один из них является указателем, а другой - нет.

Err ... на самом деле, это единственная разница междуих: одна переменная-указатель, другая нормальная переменная .Любое другое отличие происходит от такого факта.Если вы уже знакомы с тем, как переменные-указатели работают в Fortran, этот ответ на этом останавливается.Если это не так, вот краткое описание.

Переменные в Fortran - это именованные ссылки на адреса в памяти, которые содержат значения, которые соответствуют по типу и характеристикам тем, которые указаны в объявлении переменной.Когда вы работаете с переменной, ее соответствующее значение в хранилище извлекается или обновляется.

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

С другой стороны, для pointer переменных это соотношение является динамическим.Система не выделяет никакого хранилища для своего базового значения автоматически, единственное место, которое занимает указатель, это целочисленная переменная, которая будет отбирать адрес, на который он в данный момент указывает.У вас есть два способа использовать его:

1) вы можете указать другую переменную и сделать так, чтобы ваш указатель ссылался на тот же адрес в памяти, что и другая переменная.Это называется указатель связи , и делает вашу переменную указателя работать как псевдоним этой другой переменной.Указатели на фортране, в отличие от других языков, набираются, и это потрясающе.Вы сможете связать только указатель на переменную, которая соответствует ему по типу, виду и рангу, а также если он помечен атрибутом target (или также является указателем).Вы можете изменить цель вашего указателя в любое время.

2) вы можете попросить систему выделить новое хранилище в памяти для этой переменной с помощью оператора allocate.Это желательно, когда вы хотите контролировать, когда хранилище будет выделено или освобождено, и приспособить его к потребностям вашей программы.Кроме того, вы можете отложить детали переменной, которая будет определена во время выполнения, например размер / границы массива или len параметров параметризованного типа.Помните, что когда вы выбираете этот способ, вы отвечаете за управление его памятью.Если вы изменили свою ссылку на другой адрес без освобождения предыдущего, другая ссылка на эту память может отсутствовать, и вы или система не сможете ее освободить, и произойдет утечка памяти.

Итак,Подводя итоги и отвечая: с помощью атрибута pointer вы можете использовать эту переменную для указания и управления другими переменными, не требуя выделения памяти, изменяя назначение цели, как вы хотите, ИЛИ вы можете управлять памятью для этой переменной вручную, откладывая ееразмер, границы и продолжительность времени выполнения.


Сказал, что я должен напомнить вам о компромиссах, которые идут с указателями гибкости, которые приносят вам.При работе с указателями есть много ошибок и тонкостей, таких как утечки памяти, висячие указатели, нарушение прав доступа, псевдонимы ..., которые могут привести к ошибкам или снижению производительности.Если единственное, что вам нужно для указателей - это динамическое выделение памяти, и вы не планируете менять свою цель, вы должны использовать вместо этого атрибут allocatable.Распределяемые переменные и компоненты также имеют динамическую память, но система будет управлять освобождением для вас, хотя вы также можете deallocate вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...