【问题标题】:Allocation of dereferenced pointer in FortranFortran 中解引用指针的分配
【发布时间】:2020-08-05 09:06:15
【问题描述】:

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

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)%pa 应该是相同的,但显然这个世界是有缺陷的。我的问题:如何正确分配abc

【问题讨论】:

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

标签: fortran


【解决方案1】:

我建议始终使您的指针无效。这样你就不会那么容易地遇到未定义指针所导致的未定义行为。

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

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

double precision, pointer :: a(:), b(:), c(:)

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

ptrs(1)%p => a

现在ptrs(1)%p指向同一个垃圾地址。

allocate(ptrs(i)%p(n))

现在分配了一个新目标,ptrs(1)%p 指向那里。 a 不受影响。

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

a => ptrs(1)%p

重要的是不要将aptrs(1)%p 视为同一事物的两个别名。他们不是。两者都是指针,都指向某个地方。您有责任确保它们始终指向同一个地址。

【讨论】:

    【解决方案2】:

    这里要注意的重要一点是,与

    allocate(ptrs(i)%p(n))
    

    你没有分配(根据问题标题)一个 dereferenced 指针。即分配不影响指针的目标分配状态。相反,此分配会为 ptrs(i)%p 创建一个新目标。

    在问题链接的答案中,目标数组本身不是指针或可分配对象,它们是显式形状数组。这会导致对您开放的方法存在细微差别。

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

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

    或者,您可以考虑只使用可分配组件:

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

    【讨论】:

      猜你喜欢
      • 2020-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-09
      • 2021-09-05
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多