Allocating Space for a Problem


Assignment :

Complete Homework 8, Read Chpt. 17 and the Web notes on I/O

New Fortran:

Arrays in argument lists; ALLOCATE, ALLOCATABLE, and DEALLOCATE statements; ALLOCATED intrinsic function; automatic arrays

Using Array Space in Subprograms

As I mentioned before, Fortran simply passes the address of a variable to a subroutine. This makes it easy to allocate space for an array at one level in your program, and then use that space in subroutines called or functions used by that level. You must however be careful to let the subprogram know the correct bounds of the array, or it may cheerfully overwrite something you don't want touched, or use unexpected pieces of data. The program array1s.f provides an example of passing array information in a standard Fortran 77 application. A partial conversion to Fortran 90 version is provided in array2s.f, and a potential problem illustrated with array2se.f . That example won't compile, because no information is provided on the size of the array, used by some Fortran 90 array constructs (e.g. csum=sum(c)). This particular problem problem is fixed in array2sf.f.

A more complete use of  Fortran 90 (and later versions) is provided in array2s.f90.  Implementing this approach requires understanding of the Fortran 90 MODULE program unit or the INTERFACE program structure.  When you realize that your subroutine will only be operating on the same set of arrays any time that it is called, it usually makes sense to communicate those arrays via a MODULE rather than through the subroutine's argument list.  Take a look at array2sM.f90 for an example of this approach.

Dynamic Allocation of Array Space

There will be times when you don't want to write a program dimensioned for the largest possible problem that you can run. Recompiling with a reset of one or more PARAMETERs (e.g. array3c.f), can be cumbersome for large programs. That was your only option for standard Fortran 77. However, Fortran 90 introduces the ALLOCATABLE array, permitting you to assign its memory space after the program starts. This can make a big difference in the size of the disk file associated with your program, and the amount of computer memory required for execution.

To use this feature you must declare the array ALLOCATABLE, using a simple ":" in the array declaration, to avoid immediate specification of its size. One quick way to do this for an array "a" is:

      real, allocatable :: a(:)
The colon between the parentheses is mandatory. You can't do something with a specific range like:

      real, allocatable :: a(0:ndim)
This makes no sense in an array with no determined size. Once your program has determined the size needed for "a", say "length", use the ALLOCATE statement:

      allocate ( a(length))
When you are done with "a", you have the option to DEALLOCATE it:

      deallocate(a)
This is really only an option in the main program. If you allocate an array within a subroutine or function but return without deallocating an array, the array becomes "undefined", and the Fortran 90 doesn't guarantee you can retrieve the contents on re-entry to the subprogram. You are also keeping memory associated with your program that you will no longer use. If you are imbedding ALLOCATE statements within conditional structures (e.g. IF,THEN,ELSE), it may not be possible to always predict whether or not a given array is ALLOCATED. You can check to see if the array is allocated with the logical intrinsic function ALLOCATED:

      if (allocated(a)) then
         print *, 'Array A is allocated'
      endif
You should also know, that if you chose to declare an array as ALLOCATABLE within a subprogram, then that array's name can't appear in the argument list of the SUBROUTINE or FUNCTION statement. The subroutine beginning:

      subroutine (b,n)
      real, allocatable :: b(:)
      allocate (b(n))
will result in a Fortran error.

Examples of ALLOCATE are provided in array3.f, array3a.f, array3b.f, and array3e.f. Be sure to obtain input decks array3a.in and array3b.in before running these problems. The program array3.f is a simple extension of array2.f, containing the use of dynamic allocation. array3a.f scans the data file to determine space requirements, then uses ALLOCATE. array3b.f simply reads a number from the input file specifying the size of arrays.

The program array3e.f shows what happens if you decide to allocate more space to an array after the first ALLOCATE. Fortran 90 forces you to make the size decision once. If gradual expansion of an array is necessary during a program, you will need to use a mixed Fortran - C program, applying the C "malloc" function, use special machine dependent memory functions, or learn to create "linked lists" with the Fortran 90 POINTER data type.

Examples of the use of ALLOCATE within subroutines are given in the program array3as.f (needs input array3a.in). It also contains an example of automatic invocation of ALLOCATE and DEALLOCATE. If an array is declared in a subprogram, using an integer from the argument list as part of its range specification.

      subroutine test(n)
      real a(1:n)
but is not in the argument list itself, then it is called an "automatic array". Space for the array is automatically allocated when the subprogram is entered, and deallocated on return from the subprogram.

One word of warning, the simplicity of these statements hides a lot of work by the computer. Use allocation and deallocation sparingly. They will eat up a relatively large amount of computer time. It is a very bad idea to use dynamic allocation within a subroutine or function that is used a large number of times by your program.

Review Questions

Test your knowledge of this material with some review questions.

Back to the Table of Contents / Home


Written and Maintained by John Mahaffy : jhm@psu.edu