Fortran多态,函数和分配

Ren*_*eno 6 polymorphism fortran memory-leaks function fortran2003

我在使用Fortran的OOP中是一个初学者,我正在尝试编写一个程序,该程序将多态变量作为参数处理.虽然我的原始代码要复杂得多(许多程序,几个派生类型等),但我可以找出一个简单的问题示例,例如:我有一个复制多态变量并略微修改此副本的过程.

我能够使用子程序成功编写我的测试程序:

MODULE my_module

type :: my_type
    real :: data
endtype my_type

type, extends(my_type) :: my_derived_type
end type my_derived_type

CONTAINS

subroutine sub_copy(old,new) 
implicit none
class(my_type), intent(in) :: old
class(my_type), allocatable, intent(out) :: new
allocate(new, source = old)
new%data = new%data + 1
end subroutine sub_copy

END MODULE my_module

PROGRAM my_prog
use my_module
implicit none
type(my_derived_type) :: x
class(my_type), allocatable :: y

x%data = 1.0
call sub_copy(x,y)
print*,y%data
deallocate(y)

END PROGRAM my_prog
Run Code Online (Sandbox Code Playgroud)

这在预期结果和内存分配/释放方面都表现良好.

但是,我一直在努力争取使用可以完成同样工作的Fortran 功能.

似乎以与子例程类似的方式定义的函数(见下文)不能简单地用作

y = fun_copy(x)
Run Code Online (Sandbox Code Playgroud)

和我的gfortran编译器(v5.0.0)抱怨:

Error: Assignment to an allocatable polymorphic variable at (1) is not yet supported
Run Code Online (Sandbox Code Playgroud)

我在这里和那里读过,我的编译器确实不支持这样的赋值.等待,我试图通过定义我自己的赋值运算符(=)来解决这个问题.以下代码有效:

MODULE my_module

type :: my_type
    real :: data
endtype my_type

type, extends(my_type) :: my_derived_type
end type my_derived_type

interface assignment(=)
  module procedure myassign
end interface

CONTAINS

function fun_copy(old) result(new) 
implicit none
class(my_type), intent(in) :: old
class(my_type), allocatable :: new
allocate(new, source = old)
new%data = new%data + 1
end function fun_copy

subroutine myassign(new,old)
class(my_type), intent(in)  :: old
class(my_type), allocatable, intent(out) :: new
allocate(new, source=old)
end subroutine

END MODULE my_module

PROGRAM my_prog
use my_module
implicit none
type(my_derived_type) :: x
class(my_type), allocatable :: y

x%data = 1.0
y = fun_copy(x)
print*,y%data
deallocate(y)

END PROGRAM my_prog
Run Code Online (Sandbox Code Playgroud)

它确实起作用,确实x创建了一个副本y.但是,检查这个简单测试程序的内存预算(我在OS X上使用Instrument软件),似乎某些内存在它结束之前没有被释放.我怀疑复制功能和赋值子程序都分配内存,我只释放一次,留下一个分配.

由于我打算在更复杂的代码中多次使用这样的例程,我真的很关心内存分配/释放.当然,我可以使用程序的子程序版本,但如果有办法,我更喜欢功能版本.

有办法处理这样的问题吗?

Cha*_*les 1

这听起来类似于我不久前关于函数与子例程的问题:

Fortran 运算符重载:函数或子例程

我认为使用允许分配和释放的子例程与使用只能分配的函数之间存在某种权衡。我建议,如果数据结构很大,请避免使用函数并坚持使用子例程。