指针

时间:2016-01-18 11:51:00

标签: pointers memory fortran

我有一个包含指针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.

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的大多数常见版本都不会接受,并且需要明确指定形状。

变量varvar1不必是可分配的。但如果出于其他原因需要它们,它们就可以。

可以编写一次用户定义的赋值,然后重载内在赋值(=)。

   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