From Newsgroup: comp.lang.fortran
On 15/11/23 19:40, GianLuigi Piacentini wrote:
Hi all,
I have a perhaps silly question, that puzzles me before committing to
write actual code.
Please consider a data structure which is basically an array of arrays
type element
integer, allocatable :: element_core(:)
end type
...
type(elements), allocatable :: array_of_elements(:)
...
allocate ( array_of_elements(some_size) )
(this is not a matrix, each element may significantly differ in size,
and someone may be long (and subjected to reallocation cycles, but his
is plain reallocation).
Now I have to increase size of previously allocated array_of_elements,
using the usual pattern (at least I think it's usual)
type(elements), allocatable :: tmp(:)
allocate ( tmp(new_size) )
tmp(1:some_size) = array_of_elements ! ***
call move_alloc(from = tmp, to = array_of_elements)
Seems to me that during the operation marked with the *** comment the various elements are also copied, and this seems vasteful.
Is there a way to avoid such copying, if it really happens ?
Perhaps making array_of_elements an array of pointers to allocated
elements ?
Thanks in advance
Gigi Piacentini
Thanks to all replier.
I ewconsidered the problem in light of the whole project, coming with 2 possible solutions:
1) since data come from analysis of several files, which do not change
during program execution, I can do a 1st pass counting dimensions, then allocate, then do a 2nd pass reading data into the data structure.
2) as suggested, I could do
type element
integer, allocatable :: element_core(:) ! an array of integers
end type
type element_pointer
type(element), pointer :: e_p => null() ! pointer to the above
end type element_pointer
type(element_pointer), allocatable :: array_of_elements(:)
allocate( array_of_elements(3) ) ! an array of 3 pointers
do i = 1, size(array_of_elements)
allocate (array_of_elements(i)%e_p%element_core(n))
! where n is the size required for the ith array of integers
end do
... ! loading integers
Now when reallocating
type(element_pointer), allocatable :: tmp(:)
allocate( tmp(new size for array of array of integers) )
! copying pointers:
tmp(1:size(array_of_elements))%e_p => array_of_elements%e_p
! during this copy, in my intention, the underlying element_cores will
not be moved
call move_alloc (from = tmp, to = array_of_elements)
However, at the moment I cannot test the above machinery, I will do it
as soon as I can restart my hobby project, which will happen in some days.
But I am still interested in the subject, and in your comments, if any.
Thanks
Gigi
--- Synchronet 3.20a-Linux NewsLink 1.114