我有一个包含指针p的类型var。 我需要将var复制到与var相同类型的另一个变量var1上(通过执行var1" =" var,在引号中,因为我不知道它是否是正确的方法,见下文)。
在我的实现中,var和var1被传递给一个子程序,该子程序需要将var1初始化为var然后修改var1。 如果我更改var1%p的值,则也会修改var%p。 因此,我需要更改var1%p指向的内存区域的值,而不修改var%p指向的内存区域。 在Fortran(2003,英特尔)中这样做的正确方法是什么?
代码示例:
type variable
real, dimension(:), pointer:: p
end type variable
subroutine init(var,var1) !This of course will not work
type (variable):: var, var1
var1=var
end subroutine
现在,我需要能够做一些相当于改变var1%p而不影响var%p的事情。我无法更改变量(我正在修改现有代码)。
以下解决方案(如果我是正确的): 我将var1声明为:
Type(variable), allocatable:: Var1
然后分配并初始化:
allocate(var1, source=var)
var1 = var
然后
call somesub(var1)
修改var1%p,具有修改var%p的结果,使得var%p等于var1%p。
编辑3: 做:
subroutine init(var,var1)
type(variable), intent(in):: var
type(variable), allocatable, intent(inout):: var1
allocate(var1%p, source=var%p)
var1%p = 2
end subroutine init
type variable:: var
type variable, allocatable:: var1
call init(var, var1)
以上编译但崩溃(无限挂起)。 改为使用:
allocate(var1, source=var)
运行但将var%p更新为1.
答案 0 :(得分:4)
当你对派生类型变量进行内在赋值时,任何指针都是使用指针赋值=>
复制的(它只复制现有内存块的地址和其他属性)。您必须确保在内存中分配了新目标,并在那里复制了数组的值。
您可以为给定类型创建自己的重载分配,而不是使用语法var1 = var1
,或者如果足够的话,您可以将正确的分配编码到子例程中:
subroutine init(var,var1) !This of course will not work
type(variable) :: var, var1 !DO NOT FORGET THIS WHEN POSTING EXAMPLES NEXT TIME!
allocate( var1%p(lbound(var%p,1):ubound(var%p,1)) )
var1%p = var%p
end subroutine
正如HighPerformance Mark评论的那样,如果你没有其他理由使用指针,那么可分配的组件会更好。
type variable
real, dimension(:), allocatable :: p
end type variable
subroutine init(var,var1) !This WILL work
type (variable):: var, var1
var1 = var
end subroutine
在您的编辑中,您遇到了同样的问题:
var1 = var
这与以前完全一样,你没有做任何改变!
另外
allocate(var1, source=var)
应该与原始代码具有相同的效果,我相信你需要
allocate(var1%p, source=var%p)
但我已经评论过,gfortran的大多数常见版本都不会接受,并且需要明确指定形状。
变量var
和var1
不必是可分配的。但如果出于其他原因需要它们,它们就可以。
可以编写一次用户定义的赋值,然后重载内在赋值(=
)。
type variable
real :: pointer :: p(:)
contains
procedure :: assign
generic :: assignment(=) => assign
end type
subroutine assign(out, in)
class(variable), intent(out) :: out
class(variable), intent(in) :: in
allocate( out%p(lbound(in%p,1):ubound(in%p,1)) )
out%p = in%p
end subroutine
然后你可以随时写var1 = var
,它会自动调用子程序assign
。