0

consider the following program which uses a derived data type that has a pointer component top(i)%cel(:,:) and tries to fill it with elements of an array arr:

program main

implicit none

integer, parameter :: ns=6, n1=2
integer:: arr(0:ns-1), clen(n1)

type comp
integer :: nc
integer, pointer :: cel(:,:)
end type comp

type(comp), allocatable :: top(:)

integer ::i,j,k,l   

open(3, file='checks.dat')


arr=[5,4,3,2,1,0] 
clen=[3,3]

allocate(top(1))
top(1)%nc=2
!************ fill the pointer component of top(1) using arr elements
i=1; j=0

do k=1,top(i)%nc
   allocate(top(i)%cel(k,clen(k))); top(i)%cel(k,:)=0

  do l=1,clen(k)
    top(i)%cel(k,l)=arr(j)
    write(3,'(4(A,I0))') 'top(',i,')%cel(',k,',',l,')= ', top(i)%cel(k,l)
    j=j+1
  end do 
end do


write(3,*)
write(3,'(A,I0,A)') '======   checking the group element ,top(',i,')%cel:'

do k=1,top(i)%nc
   do l=1,size(top(i)%cel,dim=2)
     write(3,*)  top(i)%cel(k,l)
   end do  
end do

end program main

The contents of the checks.dat file are:

top(1)%cel(1,1)= 5
top(1)%cel(1,2)= 4
top(1)%cel(1,3)= 3
top(1)%cel(2,1)= 2
top(1)%cel(2,2)= 1
top(1)%cel(2,3)= 0

======   checking the group element ,top(1)%cel:
       0
       0
       0
       2
       1
       0

The first write shows me that top(i)%cel(1,3)=[5, 4, 3] and top(i)%cel(2,3)=[2, 1, 0], as I wanted. However when the loop ends and I check the elements I see that top(i)%cel(1,3)=[0, 0, 0]

What am I doing wrong?

geom
  • 195
  • 8
  • 2
    What are you trying to do with `allocate(top(i)%cel(k,clen(k)))` in the loop? You are aware that there's going to be lots of deallocations happening, losing access to all previous versions of `top(i)%cel`? (For that matter, why are you using pointers? Can we better help you by saying "don't use pointers, use allocatables"?) – francescalus Jul 12 '23 at 10:49
  • @francescalus It seems that `top(1)%cel(1,:)` is lost, but I cannot understand the reason. After the loop, both `top(1)%cel(1,:)` and `top(1)%cel(2,:)` should survive, no? – geom Jul 12 '23 at 11:01
  • 1
    From your comment, it sounds like you are thinking `allocate(x(1,5)); allocate(x(2,7))` does something like making `x` an array with different extents for `x(1,:)` and `x(2,:)`. It [doesn't](https://stackoverflow.com/q/18316592/3157076). – francescalus Jul 12 '23 at 11:06
  • @francescalus I use pointers because the filling of the `top(1)%cel(1,3)` and `top(1)%cel(2,3)` is done in a subroutine in my code. No I don't think what you are writing in your last comment – geom Jul 12 '23 at 11:16
  • 1
    In the `k=2` iteration you allocate the component to shape `[2,3]` but nowhere do you assign to the section `(1,:)`, just `(2,:)`. `top(i)%cel(1,:)` remains undefined, it doesn't take the values of the array you threw away when you reallocated `top(i)%cel`. Which comes back to: why are you allocating new lumps of memory more than once? – francescalus Jul 12 '23 at 11:23
  • @francescalus yes you are right! I couldn't see it, maybe because I thought that `top(i)%cel(1,3)` and `top(i)%cel(2,3)` are independent – geom Jul 12 '23 at 11:31
  • 1
    `top%cel(:,:)` is a single object, you can't first `allocate(top%cel(1,n))`, then `allocate(top%cel(2,n))`: the latter is actually equivalent to `allocate(top%cell(1:2,:))`, and the former allocation is lost (with memory leak because you didn't deallocate it). – PierU Jul 12 '23 at 11:50
  • @francescalus One solution is to define a derived data type containing another derived data type, any other suggestions? – geom Jul 12 '23 at 12:35
  • 1
    The point is that from the piece of code you are showing, the reason why you want to allocate `top%cel(:,:)` piece by piece is definitely not obvious. Why don't you do `allocate(top%cell(top(i)%nc,clen))` in one go before the loop on `k` ? Is that because the second dimension (`clen`) may vary with k? – PierU Jul 12 '23 at 14:40
  • @PierU Yes, you are correct – geom Jul 12 '23 at 17:32
  • 1
    OK, so indeed a nested derived type is a possible solution. – PierU Jul 12 '23 at 18:26
  • 1
    So my [earlier comment](https://stackoverflow.com/questions/76669645/fortran-pointers-in-derived-data-type#comment135173196_76669645) _is_ what you need? Derived types are by far the most natural way to address that, as shown in answer to that linked question. – francescalus Jul 12 '23 at 19:44
  • @francescalus feel free to post an answer if you want. I addressed it using a nested derived data type, the link to the question you provided is a bit "clumsy" explained if I may say so, but thanks anyways – geom Jul 12 '23 at 19:47

0 Answers0