

Fortran 90 includes dynamic memory allocation with a vengeance. It introduces the concept of pointers, automatic arrays, and allocatable arrays; however, be careful! Dynamic memory allocation & deallocation is expensive and it's generally better to avoid repetitious use of it in often called routines.
The following example demonstrates where a data array could be tailored to the problem size, thus minimizing program memory requirements which could be determined at run-time. The allocation is expected to be infrequent, and the data arrays are expected to be shared through out the program.
The module CONTAINS two routines that ``construct'' and ``destruct'' the arrays, as if in an object-oriented language. However, for Fortran 90 these routines will need to be called explicitly since such constructors and destructors are not called automatically. As with C++ an optional argument can be passed to the constructor to pre-set all the array values to a specified value. If no arguments are given, pre-set to zero.
Code examples
module data_array implicit none ! allocatable arrays are always assumed-shape real, dimension(:,:), allocatable :: datarr, tadarr contains ! will emulate object-like constructors and destructors ! the difference is that they are not called automatically ! as arrays come into and out of scope ! construct data arrays function ctor_dat(dim1,dim2, value) logical :: ctor_dat ! returns .TRUE. if OK integer, intent(in) :: dim1, dim2 real, intent(in), optional :: value ! preset dat to value integer :: istat real :: val ! good design requires that we test for every ! conceivable or likely failure and notify the caller ctor_dat = .FALSE. ! assume the worst allocate(datarr(dim1,dim2), stat=istat) ! allocate space if (istat .ne. 0) then return endif allocate(tadarr(dim2,dim1), stat=istat) if (istat .ne. 0) then deallocate(datarr) ! return memory return endif ! use OPTIONAL arguments for unlikely requirements if (present(value)) then val = value else val = 0.0 endif datarr = val ! preset arrays tadarr = val ctor_dat = .TRUE. ! everything OK return end function ctor_dat ! destroy data arrays function dtor_dat() logical :: dtor_dat ! returns .TRUE. if OK integer :: istat1, istat2 dtor_dat = .FALSE. ! assume the worst deallocate(datarr, stat=istat1) ! deallocate space deallocate(tadarr, stat=istat2) if (istat1 .eq. 0 .and. istat2 .eq. 0) then dtor_dat = .TRUE. endif return end function dtor_dat end module data_array program talloc use data_array implicit none ! try 2x3 case if (.not. ctor_dat(dim1=2,dim2=3,value=-1.0)) then stop 'Error 2x3 ctor' endif write (*,*) "dat = ", datarr write (*,*) "tad = ", tadarr if (.not. dtor_dat()) then stop 'Error 2x3 dtor' endif ! try 3x4 case if (.not. ctor_dat(dim1=3,dim2=4)) then stop 'Error 3x4 ctor' endif write (*,*) "dat = ", datarr write (*,*) "tad = ", tadarr datarr = reshape(source=(/ 1.,2.,3., 2.,3.,4., 3.,4.,5., 4.,5.,6./), & shape=(/3,4/)) write (*,*) "dat = ", datarr tadarr = transpose(datarr) write (*,*) "tad = ", tadarr write (*,*) "dat*tad = ", matmul(datarr,tadarr) write (*,*) "tad*dat = ", matmul(tadarr,datarr) if (.not. dtor_dat()) then stop 'Error 3x4 dtor' endif stop 'Normal end' end program talloc
dat = -1. -1. -1. -1. -1. -1. tad = -1. -1. -1. -1. -1. -1. dat = 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. tad = 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. dat = 1. 2. 3. 2. 3. 4. 3. 4. 5. 4. 5. 6. tad = 1. 2. 3. 4. 2. 3. 4. 5. 3. 4. 5. 6. dat*tad = 30. 40. 50. 40. 54. 68. 50. 68. 86. tad*dat = 14. 20. 26. 32. 20. 29. 38. 47. 26. 38. 50. 62. 32. 47. 62. 77. STOP Normal end statement executed

