Pointers 派生类型的Fortran 90/95指针
我有一个派生类型,其指针指向第二个派生类型的数组Pointers 派生类型的Fortran 90/95指针,pointers,fortran,derived-types,Pointers,Fortran,Derived Types,我有一个派生类型,其指针指向第二个派生类型的数组 TYPE vertex REAL :: x, y, z END TYPE TYPE path TYPE(vertex), DIMENSION(:), POINTER :: vertices => NULL() END TYPE 其目的是使顶点数组的大小可调整,以便可以将任意数量的顶点添加到数组中。我已经创建了代码,将顶点附加到该指针上 SUBROUTINE path_append_vertex(this, x, y, z)
TYPE vertex
REAL :: x, y, z
END TYPE
TYPE path
TYPE(vertex), DIMENSION(:), POINTER :: vertices => NULL()
END TYPE
其目的是使顶点数组的大小可调整,以便可以将任意数量的顶点添加到数组中。我已经创建了代码,将顶点附加到该指针上
SUBROUTINE path_append_vertex(this, x, y, z)
IMPLICIT NONE
!-------------------------------------------------------------------------------
! Variable declarations.
!-------------------------------------------------------------------------------
TYPE(path), INTENT(inout) :: this
REAL, INTENT(in) :: x, y, z
!-------------------------------------------------------------------------------
! Local Variable declarations.
!-------------------------------------------------------------------------------
INTEGER :: status
TYPE(vertex), DIMENSION(:), ALLOCATABLE :: vertices
!-------------------------------------------------------------------------------
! Start of executable code
!-------------------------------------------------------------------------------
IF (ASSOCIATED(this%vertices)) THEN
! Create a temporary array the same size as current number of vertices. Copy the
! contents of the old array to the new array then delete the old array.
ALLOCATE(vertices(SIZE(this%vertices)), STAT = status)
CALL check_status(status)
vertices = this%vertices
DEALLOCATE(this%vertices)
! Create a new array with one extra element. Copy the contents of the temporary
! array to the new one the delete the temporary array.
ALLOCATE(this%vertices(SIZE(vertices) + 1), STAT = status)
CALL check_status(status)
this%vertices(1:SIZE(vertices)) = vertices
DEALLOCATE(vertices)
this%vertices(SIZE(this%vertices))%x = x
this%vertices(SIZE(this%vertices))%y = y
this%vertices(SIZE(this%vertices))%z = z
ELSE
ALLOCATE(this%vertices(1), STAT = status)
CALL check_status(status)
this%vertices(1)%x = x
this%vertices(1)%y = y
this%vertices(1)%z = z
ENDIF
END SUBROUTINE
我创建了一些路径对象
TYPE ipch_desc
...
TYPE(path) :: chordPath
END TYPE
SUBROUTINE ipch_desc_construct(this, ...)
...
TYPE (ipch_desc), INTENT(inout) :: this
...
! Must NULL out the vertices array or else it will point to the last
! integration_path created in memory. Not sure why these are defaulting
! to NULL
this%chordPath%vertices => NULL()
CALL path_append_vertex(this%chordPath, xcart_i(1), xcart_i(2), xcart_i(3))
CALL path_append_vertex(this%chordPath, xcart_f(1), xcart_f(2), xcart_f(3))
! Check the value of the path vertices.
write(*,*) this%chordPath%vertices
END SUBROUTINE
一切都很好,我得到了每个顶点的正确值。例如,对于我创建的三个路径对象
-0.33808113528699218 1.0467574437103653 0.10713720000000000 -0.16057879084545851 0.49717960298733294 0.10713720000000000
-0.33322243268266594 1.0483142707971911 1.42240000000000010E-003 -0.14945358419461796 0.47017940500485894 1.42240000000000010E-003
-0.33656460666251325 1.0472460386853264 -0.10629900000000000 -0.15821659220752302 0.49230280357365630 -0.10629900000000000
在代码中使用这些路径对象时
SUBROUTINE ipch_mc_model_compute(a_ipch, ...)
...
TYPE (ipch_desc), INTENT (inout) :: a_ipch
...
! Check the value of the path vertices again.
write(*,*) a_ipch%chordPath%vertices
...
END SUBROUTINE
只有前N-1个值保持正确。对于上面创建的相同值
-0.33808113528699218 1.0467574437103653 0.10713720000000000 -0.16057879084545851 0.49717960298733294 0.10713720000000000
-0.33322243268266594 1.0483142707971911 1.42240000000000010E-003 -0.14945358419461796 0.47017940500485894 1.42240000000000010E-003
0.15094203233057696 6.94277920927416864E-310 -0.10629900000000000 1.63041663127611360E-322 3.01884064661153912E-003 6.94277920927179713E-310
无论我创建了多少个
path
对象,第n个总是以错误的值结束。是什么原因造成的?您的代码似乎正确。你可以简化一下。为什么派生类型路径包含单个变量?可以直接调整VERTEX类型数组的大小,而无需此附加类型。此外,我认为没有理由使用指针;可分配的就足够了。Fortran 2003提供了MOVE_ALLOC,这也提供了简化(如果您正在使用的编译器中有此功能)(请参阅)
我知道问题出在哪里了。正在将
ipch_desc
对象构造为一个临时对象,然后将其分配给数组中的一个元素
ipch_desc_arr(icount_chords) = ipch_desc_temp
我需要删除这个临时的或重载默认赋值运算符来修复它。如果您编写自己的答案,您可能也应该接受它。
ipch_desc_arr(icount_chords) = ipch_desc_temp