user2885778
user2885778

Reputation: 65

array of pointers fortran

Again, array of pointers in Fortran. So well, I've a derived type:

type :: t_context_pointer  
    type(t_context),pointer :: p_ctx  
end type t_context_pointer

When I do in the main program:

type(t_context_pointer),allocatable :: tab_ctx_ptr(:)  
type(t_context),allocatable,target :: ctx  
allocate(tab_ctx_ptr(1))  
allocate(ctx)  
tab_ctx_ptr(1)%p_ctx=>ctx

it works. But when I use a function call:

type(t_context_pointer),allocatable,target :: tab_ctx_ptr(:)
allocate(tab_ctx_ptr(n))
call alloc_ctx(tab_ctx_ptr,n,1)

with elsewhere:

subroutine alloc_ctx(tab_ctx_ptr,n,i)
    integer,intent(in) :: n,i
    type(t_context_pointer),intent(inout) :: tab_ctx_ptr(n)

    type(t_context),allocatable,target :: ctx

    allocate(ctx)
    tab_ctx_ptr(i)%p_ctx=>ctx
end subroutine

it seg_fault later in the code. Is there something wrong here?

Upvotes: 2

Views: 491

Answers (1)

Alexander Vogt
Alexander Vogt

Reputation: 18118

ctx is in the scope of the subroutine alloc_ctx and gets deallocated as soon as you leave the subroutine. Accessing it later (by means of the pointer) will cause a segfault.

In the first example, you allocate ctx in the main program, so its scope will be until the end of the program.

Why don't you allocate tab_ctx_ptr(i)%p_ctx directly:

subroutine alloc_ctx(tab_ctx_ptr,n,i)
    integer,intent(in) :: n,i
    type(t_context_pointer),intent(inout) :: tab_ctx_ptr(n)

    allocate(tab_ctx_ptr(i)%p_ctx)
end subroutine

As for deallocation: You could use something like this to deallocate all pointers (but not the array itself):

subroutine dealloc_ctx(tab_ctx_ptr,n)
    integer,intent(in) :: n
    type(t_context_pointer),intent(inout) :: tab_ctx_ptr(n)
    integer            :: i

    do i=1,n
      ! Check whether the current element has an allocated element and 
      ! deallocate if necessary. 
      if ( associated(tab_ctx_ptr(i)%p_ctx) ) deallocate(tab_ctx_ptr(i)%p_ctx)
    enddo ! i
end subroutine

Upvotes: 4

Related Questions