How to increase array size on-the-fly in Fortran?
If you declare an array allocatable, you use deffered shape in the form real,
allocatable :: labelArray(:,:)
, or
real,dimension(:,:),allocatable :: labelArray
with number of double colons meaning rank (number of your indexes) of your array.
If the array is unallocated you use
allocate(labelarray(shapeyouwant))
with the correct number of indexes. For example allocate(labelarray(2:3,-1:5))
for array with indexes 2 to 3 in demension 1 and -1 to 5 in dimension 2.
For change of dimension you have to deallocate the array first using
deallocate(labelArray)
To reallocate an allocated array to a new shape you first need to allocate a new array with the new shape, copy the existing array to the new array and move the reference of the old array to the new array using move_alloc()
.
call allocate(tmp(size_old+n_enlarge))
tmp(1:size_old) = array(1:size_old)
call move_alloc(tmp, array)
The old array is deallocated automatically when the new array reference is moved by move_alloc()
.
Fortran 95 deallocates arrays automatically, if they fall out of scope (end of their subroutine for example).
Fortran 2008 has a nice feature of automatic allocation on assignment. If you say array1=array2
and array1 is not allocated, it is automatically allocated to have the correct shape.
It can also be used for re-allocation (see also Fortran array automatically growing when adding a value and How to add new element to dynamical array in Fortran 90)
labelArray = [labelArray, new_element]
Late comment... check Numerical Recipes for Fortran 90. They implemented a nice reallocate function that was Fortran 90 compliant. Your arrays must be pointer attributed in this case, not allocatable attributed.
The function receives the old array and desired size, and returns a pointer to the new resized array.
If at all possible, use Fortran 95 or 2003. If 2003 is impossible, then 95 is a good compromise. It provides better pointer syntax.
Here is a Stack Overflow question with some code examples showing several ways of using Fortran allocatable arrays: How to get priorly-unkown array as the output of a function in Fortran: declaring, allocating, testing for being already being allocated, using the new move_alloc and allocation on assignment. Not shown there is explicit deallocation, since the examples are using move_alloc and automatic deallocation on exit of a procedure.
P.S. If you want to repeatedly add one element you should think about your data structure approach. Adding one element at a time by growing an array is not an efficient approach. To grow an array from N elements to N+1 in Fortran will likely mean creating a new array and copying all of the existing elements. A more appropriate data structure might be a linked list. You can create a linked list in Fortran by creating a user-defined type and using pointers. You chain the members together, pointing from one to the next. The overhead to adding another member is minor. The drawback is that it is easiest to access the members of the list in order. You don't have the easy ability of an array, using indices, to access the members in any order.
Info about linked lists in Fortran that I found on the web: http://www-uxsup.csx.cam.ac.uk/courses/Fortran/paper_12.pdf and http://www.iag.uni-stuttgart.de/IAG/institut/abteilungen/numerik/images/4/4c/Pointer_Introduction.pdf