【问题标题】:Copying pointer association in a Fortran derived type structure在 Fortran 派生类型结构中复制指针关联
【发布时间】:2020-02-09 02:12:41
【问题描述】:

我正在尝试将目标复制到派生类型变量中的指针到另一个相同类型的变量,但我不知道该怎么做

假设我有一个分散的点列表,我想对其进行三角测量。我会有一个

type :: triangulation
   type(vertex), allocatable :: points(:)
   type(triangle), allocatable :: triangles(:)
end type triangulation

为了节省内存,我使用指向节点的指针来定义每个三角形:

type :: triangle
   type(vertex), pointer :: A => null()
   type(vertex), pointer :: B => null()
   type(vertex), pointer :: C => null()
end type triangle

这将在同一个对象中。例如,要在三角剖分中生成一个新三角形,我将运行:

type(triangle) function triangulation_new_triangle(this,iA,iB,iC) result(tri)
   class(triangulation), intent(in), target :: this
   integer, intent(in) :: iA, iB, iC ! Indices of the three nodes

   tri%A => this%points(iA)
   tri%B => this%points(iB)
   tri%C => this%points(iC)

end function 

现在,假设我必须重新分配三角形列表。如何将其复制到相同三角剖分的新列表中,而不会丢失其指针引用?即,我想做这样的事情:

subroutine triangulation_reallocate(this)
   class(triangulation), intent(inout) :: this

   ! Local variables
   integer, parameter :: TRIANGLE_CHUNK_SIZE = 1024
   integer :: old_size
   type(triangle), allocatable :: new_triangle_pool(:)

   ! Get old size
   old_size = merge(size(this%triangles),0,allocated(this%triangles))

   ! Allocate new array of triangles
   allocate(new_triangle_pool(old_size+TRIANGLE_CHUNK_SIZE))

   ! Copy data from old to new array
   [..... missing code here .......]

   ! Move allocation back to the triangulation object
   call move_alloc(from=new_triangle_pool,to=this%triangles)

end subroutine triangulation_reallocate

我正在考虑一种复制三角形关联的方法。如果我这样做:

do i=1,old_size
   new_triangle_pool(i) = this%triangles(i)
end do

这行得通吗?我担心如果我复制以下内容:

new_triangle_pool(i)%A => this%triangles(i)%A

那么这是一个指向指针而不是指向原始顶点的指针,当旧的this%triangles 变量被释放时关联会丢失?

【问题讨论】:

  • 您是否关心y=>z; x=>y的最终效果是否像x=>z
  • 是的:我想要x=>z,但是套路不知道z是什么;另外,中间的y 将通过调用move_alloc 被释放

标签: oop pointers fortran fortran2003


【解决方案1】:

您的建议应该有效。然而,一个更简单的建议:

new_triangle_pool = this%triangles

由于new_triangle_poolALLOCATABLE,因此该数组应自动分配为分配源 (this%triangles) 的大小,然后通过源中的元素复制进行初始化。

默认情况下,派生类型的指针组件被复制为浅拷贝。这意味着没有重复的内存,而是new_triangle_pool 的每个元素上的ABC 指针将与AB 和@ 相同的目标相关联987654331@ 指向this%triangles 的对应元素。如果this%triangles 元素上的指针与其他目标关联或无效,则new_triangle_pool 上的指针将保持与原始目标关联。

遇到问题的唯一方法是,如果 this%triangles 上的指针被释放而不是被取消。那时,内存将不再被分配,您将在new_triangle_pool 上留下悬空指针。不过,只要小心,您就可以避免这个问题。

如果需要深拷贝(即分配new_triangle_pool 中的指针,然后将this%triangles 中的值复制到新内存中),则必须显式编写代码来执行此操作。否则,默认情况下只会进行浅拷贝(我相信这是您想要的)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 2023-03-26
    相关资源
    最近更新 更多