Fortran中解引用指针的分配

Fortran中解引用指针的分配,fortran,Fortran,我正试图用Fortran 90创建一个指针数组,如上所述。然后,该数组中的每个指针都与一个浮点数组相关联,在运行时通过取消对指针的引用进行分配。请参见以下示例: program test type ptr double precision, pointer :: p(:) end type ptr integer :: i, n=5 type(ptr), dimension(3) :: ptrs double precision, poi

我正试图用Fortran 90创建一个指针数组,如上所述。然后,该数组中的每个指针都与一个浮点数组相关联,在运行时通过取消对指针的引用进行分配。请参见以下示例:

program test
    type ptr
        double precision, pointer :: p(:)
    end type ptr

    integer :: i, n=5
    type(ptr), dimension(3) :: ptrs
    double precision, pointer :: a(:), b(:), c(:)

    ptrs(1)%p => a
    ptrs(2)%p => b
    ptrs(3)%p => c

    do i=1,3
        allocate(ptrs(i)%p(n))
        ptrs(i)%p = 0d0
    enddo

    write(6, *) ptrs(1)%p
    write(6, *) a

end program test
结果:

$ gfortran -o test test.f90 && ./test                                                                                                 
0.0000000000000000        0.0000000000000000        0.0000000000000000        0.0000000000000000        0.0000000000000000
At line 20 of file test.f90 (unit = 6, file = 'stdout')
Internal Error: list_formatted_write(): Bad type

抛出错误是因为未分配
a
。在理想世界中,
ptrs(1)%p
a
应该是相同的,但显然这个世界是有缺陷的。我的问题:如何正确分配
a
b
c

我建议始终将指针置零。这样,您就不会那么容易地碰到未定义指针所导致的未定义行为

对于派生类型,可以使用默认初始化

type ptr
    double precision, pointer :: p(:) => null()
end type ptr

指针
a
指向一些未定义的垃圾地址

ptrs(1)%p => a
allocate(ptrs(i)%p(n))
现在
ptrs(1)%p
指向相同的垃圾地址

ptrs(1)%p => a
allocate(ptrs(i)%p(n))
现在分配了一个新的目标,并且
ptrs(1)%p
指向那里<代码>a不受影响

相反,您现在还必须将
a
指向该新地址

a => ptrs(1)%p

<>重要的是不要考虑<代码> A<代码> >代码> PTRS(1)%P<代码>是同一事物的两个别名。事实并非如此。两者都是指针,都指向某处。您有责任确保他们始终指向同一地址。

这里需要注意的重要一点是

ptrs(1)%p => a
allocate(ptrs(i)%p(n))
allocate(ptrs(i)%p(n))
您没有分配(根据问题标题)取消引用的指针。也就是说,分配不会影响指针的目标分配状态。相反,这种分配为
ptrs(i)%p
创建了一个新的目标

在与问题相关联的答案中,目标数组本身不是指针或可分配对象,而是显式形状数组。这就导致了对你开放的方法的细微差别

如果希望与组件指针的目标使用动态关联,则可以在分配目标后将指针指向目标。比如:

allocate(a(n))
ptrs(1)%p => a

可选地,您可以考虑只使用可分配组件:

type ptr
  double precision, allocatable :: p(:)
end type ptr

请在Fortran问题中使用tag,同样,几十年来(自Fortran 90以来),这种语言一直被称为Fortran,而不是Fortran。这两个答案都很好地描述了您的错误。作为进一步的评论,如果可能的话,您应该避免使用指针。是的,我知道链接列表和队列之类的东西需要指针。