可分配的用户派生类型

时间:2013-05-07 12:06:19

标签: types fortran allocation

我有关于Fortran和正确分配的问题 可分配的用户派生类型。

这是我的代码:

module polynom_mod
 implicit none

 type monomial
  integer,dimension(2) :: exponent
 end type

type polynom
  real, allocatable, dimension(:) :: coeff
  type(monomial),allocatable, dimension(:)   :: monom
  logical :: allocated
 !recursive type
  type(polynom),pointer :: p_dx,p_dy
 contains
  procedure :: init
  procedure :: init_dx
end type

这里我想得到一个类型多项式,我可以做以下事情:

p%coeff(1)=1.0 
p%monom(1)%exponent(1)=2

等等:

p%p_dx%coeff(1)=1.0 
p%p_dx%monom(1)%exponent(1)=2

所以我写了一些init类型绑定的程序,我可以初始化我的并分配我的 类型:

contains

function init(this,num) result(stat)
  implicit none
  integer, intent(in)      :: num
  class(polynom),intent(inout) :: this
  logical :: stat

  allocate(this%coeff(num))
  allocate(this%monom(num))

  this%allocated = .TRUE.
  stat = .TRUE.
end function

function init_dx(this,num) result(stat)
  implicit none

  integer, intent(in)      :: num
  class(polynom),intent(inout) :: this

  logical :: stat

  allocate(this%p_dx%coeff(num))
  allocate(this%p_dx%monom(num))

  this%p_dx%allocated = .TRUE.
  stat = .TRUE.
 end function   
end module

program testpolytype
 use polynom_mod

 type(polynom) :: p

 if(p%init(2)) then
  print *,"Polynom allocated!"
 end if

 if(p%p_dx%init_dx(2)) then
  print *,"Polynom_dx allocated!"
 end if

结束程序

这将使用gfortran 4.6.3进行编译,但是当我运行它时,我遇到了分段错误!

有没有办法分配递归的可分配类型?

2 个答案:

答案 0 :(得分:2)

您的代码的表面问题是,当计算表达式p%p_dx%init_dx(2)时,指针组件p%p_dx未定义,并且引发了分段错误。请注意,指针未定义而不仅仅未关联

现在我正在努力想出一个快速解决方案。长期解决方案是解决我认为你的方法中的一个严重缺陷;请注意,这是我的看法,而不是黑色或白色的问题所以只有在你关心我的输入时才能阅读。

函数initinit_dx并没有副作用,实际上它们可以说几乎都是副作用 - 它们返回逻辑值,并且作为副作用,初始化polynom变量。该程序似乎无法在不评估polynom的情况下初始化init,并且无法在不将其包含在诸如

之类的语句中的情况下评估init
if (p%init(2)) then
end if

我想,您可以将这些初始化函数重写为子例程,也许可以使用签名,例如

call initialise_polynom(p,2)

这至少会从代码中删除不纯函数的污点。但更好的方法是编写一个函数,如:

function new_poly(num)
  implicit none
  integer, intent(in) :: num
  type(polynom) :: new_poly
  allocate(new_poly%coeff(num))
  allocate(new_poly%monom(num))
  allocate(new_poly%p_dx)
end function new_poly

哪个

a)返回一个新的polynom;和

b)分配组件p_dx;和

c)无副作用。

然后,您可以使用

等表达式创建新的polynom
p = new_poly(3)

并使用诸如

之类的表达式初始化组件
p%p_dx = new_poly(3)

答案 1 :(得分:0)

回答我自己的问题,我提出了另一个解决方案,女巫也没有指针,但它不像Marks那样优雅。

定义另一种类型:

type p_dx
 real, allocatable, dimension(:) :: coeff
 type(monomial),allocatable, dimension(:)   :: monom
 logical :: allocated
end type

然后将其用于:

type polynom
 real, allocatable, dimension(:) :: coeff
 type(monomial),allocatable, dimension(:)   :: monom
 type(p_dx) :: dx
 logical :: allocated
contains
 procedure     :: init
end type

所以你可以这样做:

type(polynom) :: p

p%init(2)
p%dx%init_dx(3)