【问题标题】:allocatable user derived types可分配的用户派生类型
【发布时间】:2013-05-01 09:10:11
【问题描述】:

我有一个关于 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

所以我写了一些初始化类型绑定的过程,我可以在其中初始化和分配我的 类型:

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 编译,但是当我运行它时,我遇到了分段错误!

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

【问题讨论】:

    标签: types fortran allocation


    【解决方案1】:

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

    现在我正在努力想出一个快速解决方案。长期的解决办法是解决我认为您的方法中的严重缺陷;请注意,这是我的意见,而不是非黑即白的问题,因此请仅在您关心我的意见的情况下继续阅读。

    函数initinit_dx 并非没有副作用,实际上它们可以说几乎都是副作用——它们返回一个逻辑值,并且作为副作用,初始化一个@ 987654325@ 变量。该程序似乎无法在不评估init 的情况下初始化polynom,并且如果不将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)
    

    【讨论】:

    • 谢谢!您对导致分段错误的未初始化指针是正确的。
    【解决方案2】:

    回答我自己的问题,我想出了另一个解决方案,女巫也可以在没有指针的情况下工作,但它不像 Mark 的那样优雅。

    定义其他类型:

    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)
    

    【讨论】:

    • 我会避免使用像 logical :: allocated 这样的变量,当您将其与固有的 allocated 函数混淆时,它只会导致悲伤和绝望。
    猜你喜欢
    • 2020-03-17
    • 2014-10-18
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多