我有一个包含指针 p 的类型 var。 我需要在另一个与 var 类型相同的变量 var1 上复制 var(通过在引号中执行 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
现在,我需要能够在不影响 var%p 的情况下做一些等同于更改 var1%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。
最佳答案
当您对派生类型变量进行内部赋值时,将使用指针赋值 =>
复制任何指针(它只复制现有内存块的地址和其他属性)。您必须确保在内存中分配了一个新目标,并将数组的值复制到那里。
您可以为给定类型创建您自己的重载赋值,而不是使用语法 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
。
关于pointers - 指针的 Fortran 副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34854078/