The problem is nothing to do with the derived type, and the error message is wrong.
The problem is that zoos(i)%ducks
is a pointer to an array, not an array of pointers, so you need to point zoos(i)%ducks
at zoos(i)%animals(:, 2)
, rather than zoos(i)%ducks(1)
at zoos(i)%animals(1, 2)
.
I have previously talked about this in this answer.
I believe this does what you want:
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
I would also like to offer a frame challenge. As noted in the comments, particularly by Ian Bush, pointers in Fortran are notoriously error-prone.
I would recommend replacing any allocated pointer
s with allocatable
s. These allocatable
s also need to be target
s if they have pointer
s pointing at them, like so:
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
There are a number of advantages to using allocatable
s over pointer
s where possible:
- The memory held by
allocatable
s will automatically be freed when the allocatable
s drop out of scope1.
- Compilers can make stronger assumptions about
allocatable
s than about pointer
s, sometimes leading to faster code.
1 At least, this is true according to the Fortran standard. There are several outstanding problems with some compilers (notably this bug) relating to finalisation.