将派生类型中的指针分配给Fortran中相同类型的目标

将派生类型中的指针分配给Fortran中相同类型的目标,fortran,Fortran,我想在同一派生类型中包含的派生类型中指定一个指针。下面的代码给出了下面的错误。这是怎么回事,我该怎么解决 24 | zoos(i)%tigers(1) => zoos(i)%animals(1, 1) | 1 Error: Expected bounds specification for 'zoos' at (1) 问题与派生类型无关,错误消息是错误的 问题是zoos(i)%ducks是指向数组的指针,而不是指针数组,因此您需要将zoos

我想在同一派生类型中包含的派生类型中指定一个指针。下面的代码给出了下面的错误。这是怎么回事,我该怎么解决

   24 |         zoos(i)%tigers(1) => zoos(i)%animals(1, 1)
      |        1
Error: Expected bounds specification for 'zoos' at (1)

问题与派生类型无关,错误消息是错误的

问题是
zoos(i)%ducks
是指向数组的指针,而不是指针数组,因此您需要将
zoos(i)%ducks
指向
zoos(i)%animals(:,2)
,而不是
zoos(i)%ducks(1)
指向
zoos(i)%animals(1,2)

我之前已经谈到过这一点

我相信这正是你想要的:

module mo_zoo
    implicit none
    type zoo
        integer, dimension(:,:), pointer :: animals
        integer, dimension(:), pointer :: tigers
        integer, dimension(:), pointer :: ducks
    end type zoo
   
    save
        type(zoo), dimension(:), pointer :: zoos
end module mo_zoo

program test
    use mo_zoo
    implicit none
    integer :: n_zoos
    integer :: i

    n_zoos = 4
    allocate(zoos(n_zoos))

    do i = 1, n_zoos
        allocate(zoos(i)%animals(10, 2))
        zoos(i)%tigers => zoos(i)%animals(:, 1)
        zoos(i)%ducks => zoos(i)%animals(:, 2)
    end do
end program test
我还想提出一个框架挑战。正如Ian Bush在评论中特别指出的那样,Fortran中的指针是出了名的容易出错的

我建议将任何已分配的
指针
s替换为
可分配的
s。这些
可分配的
s也需要是
目标
s,如果它们有
指针
s指向它们,如下所示:

module mo_zoo
    implicit none
    type zoo
        integer, dimension(:,:), allocatable :: animals
        integer, dimension(:), pointer :: tigers
        integer, dimension(:), pointer :: ducks
    end type zoo
   
    save
        type(zoo), dimension(:), allocatable, target :: zoos
end module mo_zoo

program test
    use mo_zoo
    implicit none
    integer :: n_zoos
    integer :: i

    n_zoos = 4
    allocate(zoos(n_zoos))

    do i = 1, n_zoos
        allocate(zoos(i)%animals(10, 2))
        zoos(i)%tigers => zoos(i)%animals(:, 1)
        zoos(i)%ducks => zoos(i)%animals(:, 2)
    end do
end program test
在可能的情况下,使用
可分配
s优于
指针
s有许多优点:

  • allocatable
    s持有的内存将在
    allocatable
    s退出作用域1时自动释放
  • 编译器可以对
    可分配
    s做出比
    指针
    s更强的假设,有时会导致更快的代码


1至少,根据Fortran标准,这是正确的。一些编译器(尤其是)在最终定稿方面存在一些突出的问题。

可能是重复的吗?我认为我的情况更复杂,因为指针包含在派生类型的数组中。可分配性几乎总是优越的——当然,这里所示的二维数组没有理由不可分配,可能目标属性取决于您所做的其他事情,但我很难理解数组的维度。为什么动物是二维数组,而老虎和鸭子是一维数组?当你做指针赋值时,你只指向一个元素,那么为什么是一维数组呢?我想指向数组中的一个范围。对不起,我的Fortran已经生锈了,这是我很长一段时间以来的第一次编码。这确实奏效了。我原以为指向第一个元素就行了,但我显然考虑了更多的C风格。我仍然会在适当的时候使用allocatables…@veryreverie我也一直在使用Gfortran作为我的主编译器(谢谢!!),我的经验是,
allocatable
派生类型中的数组现在非常成熟/稳定,我最近基本上没有遇到任何问题(例如,即使是嵌套可分配对象的“深度复制”)。但我仍然避免使用(1)
final
例程(以及对象的意图(out)),和(2)多态分配+LHS的自动分配(相反,我使用源分配,如
allocate(objA,source=objB)
)。考虑到这两个注意事项,我认为
allocatable
可以使用(或推荐),特别是当gfort>=10:)(FWIW,没有声明答案,但我觉得有点过于担心(?)可分配组件…),如果可能的话,将结果与至少两个编译器(ifort和gfort)进行比较可能是一个有用的建议(尽管我总是忘记这么做…XD),我在gfortran中广泛使用inten(out)和多态分配+LHS的自动分配,并且最近没有出现任何问题(gfortran 7+)。不过我不太使用定稿功能——这是一个让我感兴趣的功能,但在考试中却不太适合我的需要。
module mo_zoo
    implicit none
    type zoo
        integer, dimension(:,:), allocatable :: animals
        integer, dimension(:), pointer :: tigers
        integer, dimension(:), pointer :: ducks
    end type zoo
   
    save
        type(zoo), dimension(:), allocatable, target :: zoos
end module mo_zoo

program test
    use mo_zoo
    implicit none
    integer :: n_zoos
    integer :: i

    n_zoos = 4
    allocate(zoos(n_zoos))

    do i = 1, n_zoos
        allocate(zoos(i)%animals(10, 2))
        zoos(i)%tigers => zoos(i)%animals(:, 1)
        zoos(i)%ducks => zoos(i)%animals(:, 2)
    end do
end program test