可分配的用户派生类型
Posted
技术标签:
【中文标题】可分配的用户派生类型【英文标题】: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 编译,但是当我运行它时,我遇到了分段错误!
有没有办法分配递归可分配类型?
【问题讨论】:
【参考方案1】:您的代码的表面问题是,当计算表达式p%p_dx%init_dx(2)
时,指针组件p%p_dx
未定义,并且引发了分段错误。请注意,指针是未定义,而不仅仅是未关联。
现在我正在努力想出一个快速解决方案。长期的解决办法是解决我认为您的方法中的严重缺陷;请注意,这是我的意见,而不是非黑即白的问题,因此请仅在您关心我的意见的情况下继续阅读。
函数init
和init_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
函数混淆时,它只会导致悲伤和绝望。以上是关于可分配的用户派生类型的主要内容,如果未能解决你的问题,请参考以下文章