Не используйте функции с указателями. Как правило, я никогда не создаю функции, которые возвращают функции. Они плохие и запутанные. Они приводят к неприятным ошибкам, особенно когда кто-то путает =>
и =
.
. Функция выполняет то, что она выделяет новый объект и создает указатель, который выделяет объект.
TypeObject = PointType(10)
делает то, что копирует значение объекта, сохраненного в указателе. Тогда указатель будет забыт, а память, на которую указывал указатель, будет утечка и потеряна навсегда.
Вы пишете «Насколько я могу судить, не будет никаких висящих указателей, и мы будем иметь больше контроля над распределением объектов. " Однако я не вижу способа избежать висящего указателя, выделенного внутри функции. Даже финализатор не может помочь здесь. Я тоже не вижу, как у вас больше контроля. Память, которую вы явно выделяете, просто потеряна. У вас есть другая память для TypeObject
(вероятно, в стеке основной программы), и массив внутри типа будет выделен снова во время копирования в присваивании intrinsi c TypeObject = PointType(10)
.
Финализатор может позаботьтесь о компоненте массива, чтобы не потерять массив, размещенный внутри функции. Однако сам тип, на который указывает указатель TypePointer
, с его неразмещаемыми компонентами, дескрипторами и дескрипторами без указателей и т. Д., Не может быть освобожден из финализатора и останется висящим, а память будет вытекать.
Не бойтесь функций, которые возвращают объекты как значения. Это не проблема. Компиляторы умны и способны оптимизировать ненужную копию. Компилятор может легко обнаружить, что вы просто присваиваете результат функции, поэтому он может использовать область памяти цели назначения для переменной результата функции (если она не должна быть размещаемой).
Многие существуют другие оптимизации.
function NewPointType(n) result(TypePointer)
integer, intent(in) :: n
type(PointType) :: TypePointer
allocate(TypePointer%array(n))
end function NewPointType
проще и должен работать просто отлично. С оптимизацией это может быть даже быстрее. Если использование не указателя неразмещаемого результата невозможно, используйте выделение. Не используйте указатели для результатов функции.