Reputation: 65
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
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