复制 Fortran 派生类型结构中的指针关联



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

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

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变量时关联会丢失吗?

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

new_triangle_pool = this%triangles

由于new_triangle_poolALLOCATABLE的,数组应该自动分配给赋值源的大小(this%triangles(,然后通过源的逐元素复制进行初始化。

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

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

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

最新更新