该问题与派生类型无关,并且错误消息是错误的。
问题是zoos(i)%ducks
是一个指向数组的指针,而不是指针数组,所以你需要指向zoos(i)%ducks
at zoos(i)%animals(:, 2)
, 而不是zoos(i)%ducks(1)
at zoos(i)%animals(1, 2)
.
我之前谈过这个在这个答案中 https://stackoverflow.com/questions/67033612/array-of-pointers-in-fortran/67056904#67056904.
我相信这符合您的要求:
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 中的指针非常容易出错。
我建议更换任何分配的pointer
s with allocatable
s。这些allocatable
还需要target
如果他们有pointer
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
使用有很多优点allocatable
s over pointer
尽可能:
- The memory held by
allocatable
s will automatically be freed when the allocatable
s drop out of scope1.
- 编译器可以做出更强有力的假设
allocatable
比大约pointer
s,有时会导致更快的代码。
1 At least, this is true according to the Fortran standard. There are several outstanding problems with some compilers (notably this bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90068) relating to finalisation.