pointers - 指针的 Fortran 副本

标签 pointers memory fortran

我有一个包含指针 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 都不会接受它,并且需要明确指定形状。

变量 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

关于pointers - 指针的 Fortran 副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34854078/

相关文章:

python - Python 如何处理您未放入变量的 TCP 响应?

fortran - 是否可以强制 Fortran 编译器使用单精度?

c++ - 如何使用指针和长度未知遍历数组?

C++ wxWidgets Gui-App关闭后保留在内存中

linux - 如何将内存从进程返回给操作系统

parallel-processing - FORTRAN 中的 OpenMP 未运行预期的线程数

c++ - 关于为什么字符串在\0的第一个实例上被截断的问题

C - 使用更多指针访问文件

pointers - 围棋之旅,引用Vector结构时&与no与之间的区别