Wikibooksβ

Fortran/memory management

Contents

Most Fortran programs prior to the Fortran90 standard used self-contained data, without structures, and without much in the way of shared, structured data. However, it was possible to share data, in structured and unstructured ways, using common blocks. Furthermore, there used to be little memory management going on in a Fortran program. Until Fortran90 allocated storage wasn't even possible, except via certain extensions (e.g. Cray pointers). Modern Fortran, however, supports many modern programming paradigms, has full support for allocatable data (including allocatable types), and allows for the use of pointers.

Since Fortran90, shared variables are conveniently managed by the use of modules. Common blocks were used to define global memory prior to the Fortran90 standard; their use in modern Fortran is discouraged. A Fortran module can also contain subroutines and functions, but we shall leave the discussion of these features for later. As for the management of shared variables, they may be defined in a module:

Note that it is considered good practice to declare any module private, even if it contains only public variables. (Although 'save' is the default for a variable in a module, meaning that it retains its previous value whenever the variables within the modules are used, it is sometimes considered good practice to make this explicit.) The module can then be used in the main program:

PROGRAM my_exampleuse shared_variables,only:shared_integer,shared_stuffimplicit noneinteger::some_local_integer! This will work and assign shared_integer to some local variable.shared_integer=some_local_integer! This will print the component my_character from type shared_stuff to stdoutwrite(*,*)shared_stuff%my_character! This, however, will not work, since another_shared_integer was not imported from the module - the program will not compileshared_integer=another_shared_integerEND PROGRAM my_example

Common blocks have been replaced by the use of public variables in modules in modern Fortran standards (Fortran90 and later). They are, however, historically important due to their use in older Fortran standards (77 and prior). A common block was Fortran's way of using shared, common storage for standards prior to Fortran90. In its simplest form, a common block is a way of defining global memory. Be careful, though. In most languages, each item in common memory is shared as a globally known name separately. In Fortran, however, the common block is a shared thing. I'll show several examples, but each example will share i and anotherInteger, and myArray, a 10x10 array of real numbers.

In C, for instance, I can define the shared memory using:

int i;int anotherInteger;float myArray[10][10];

and use these data elsewhere with:

externfloat myArray[10][10];externint i;externint anotherInteger;

Note that one module declares the storage, and another uses the storage. Also note that the definitions and usages are not in the same order. This is because in C, as in most languages, i, anotherInteger, and myArray are all shared items. Not so in Fortran. In Fortran, all routines sharing this storage would have a definition something like this:

This common block is stored as a block of data, as a linkable named structure. The only problem is that we don't know its name. Various compilers will give various names to this block. In some systems, the block actually doesn't have a name. We can avoid this problem by giving the structure a name. For instance,

Using this form, two different Fortran programs can identify the same area of storage and share it, without having to know the structure of all shared storage. Also using this format, a C or other program could share the storage. For instance, a C program wanting to share this storage would declare the same storage as follows:

externstruct{int i;int anotherInteger;float myArray[10][10];}myBlock;

In the above example, having the myBlock names match is critical, as well as having the types, sizes, and order match. However, having the names internally match is not since these names are known only locally. Also note that in the above example, Fortran's myArray(i,j) matches C's myBlock.myArray[j][i].