title: Dynamic array allocation in fortran90
body: <p>I am writing a generic subroutine in fortran90 that will read in a column of data (real values).  The subroutine should first check to see that the file exists and can be opened, then it determines the number of elements (Array_Size) in the column by reading the number of lines until end of file.  Next the subroutine rewinds the file back to the beginning and reads in the data points and assigns each to an array (Column1(n)) and also determines the largest element in the array (Max_Value).  The hope is that this subroutine can be written to be completely generic and not require any prior knowledge of the number of data points in the file, which is why the number of elements is first determined so the array, "Column1", can be dynamically allocated to contain "Array_Size" number of data points. Once the array is passed to the main program, it is transferred to another array and the initial dynamically allocated array is deallocated so that the routine can be repeated for multiple other input files, although this example only reads in one data file. </p>
  
  <p>As written below, the program compiles just fine on the Intel fortran compiler; however, when it runs it gives me a severe (174): SIGSEV fault.  I place the write(<em>,</em>) statements before and after the allocate statement in the subroutine and it prints the first statement "Program works here", but not the second, which indicates that the problem is occurring at the ALLOCATE (Column1(Array_Size)) statement, between the two write(<em>,</em>) statements.  I re-compiled it with -C flag and ran the executable, which fails again and states severe (408): "Attempt to fetch from allocatable variable MISC_ARRAY when it is not allocated".  The variable MISC_ARRAY is the dummy variable in the main program, which seems to indicate that the compiler wants the array allocated in the main program and not in the subprogram.  If I statically allocate the array, the program works just fine.  In order to make the program generic and not require any knowledge of the size of each file, it needs to be dynamically allocated and this should happen in the subprogram, not the main program.  Is there a way to accomplish this that I am not seeing?</p>
  
  <pre><code>         PROGRAM MAIN
           IMPLICIT NONE
    ! - variable Definitions for MAIN program
           INTEGER :: n
    ! - Variable Definitions for EXPENSE READER Subprograms
           REAL, DIMENSION(:), ALLOCATABLE :: Misc_Array,MISC_DATA
           INTEGER :: Size_Misc
           REAL :: Peak_Misc_Value
    !       REAL :: Misc_Array(365)
           CHARACTER(LEN=13) :: File_Name
          File_Name = "Misc.txt"
          CALL One_Column(File_Name,Size_Misc,Peak_Misc_Value,Misc_Array)
          ALLOCATE (MISC_DATA(Size_Misc))
          DO n = 1,Size_Misc ! Transfers array data
           MISC_DATA(n) = Misc_Array(n)
          END DO
          DEALLOCATE (Misc_Array)
          END PROGRAM MAIN
  
          SUBROUTINE One_Column(File_Name,Array_Size,Max_Value,Column1)
  
          IMPLICIT NONE
          REAL, DIMENSION(:), ALLOCATABLE,INTENT(OUT) :: Column1
     !     REAL :: Column1(365)
          REAL, INTENT(OUT) :: Max_Value
          CHARACTER,INTENT(IN) :: File_Name*13
          INTEGER, INTENT(OUT) :: Array_Size
          INTEGER :: Open_Status,Input_Status,n
  
     ! Open the file and check to ensure it is properly opened
          OPEN(UNIT=100,FILE = File_Name,STATUS = 'old',ACTION = 'READ', &amp;
               IOSTAT = Open_Status)
          IF(Open_Status &gt; 0) THEN
           WRITE(*,'(A,A)') "**** Cannot Open ",File_Name
           STOP
           RETURN
          END IF
     ! Determine the size of the file
          Array_Size = 0
          DO 300
          READ(100,*,IOSTAT = Input_Status)
          IF(Input_Status &lt; 0) EXIT
          Array_Size = Array_Size + 1
     300  CONTINUE
          REWIND(100)
          WRITE(*,*) "Program works here"
          ALLOCATE (Column1(Array_Size))
          WRITE(*,*) "Program stops working here"
          Max_Value = 0.0
          DO n = 1,Array_Size
           READ(100,*) Column1(n)
           IF(Column1(n) .GT. Max_Value) Max_Value = Column1(n)
          END DO
          END SUBROUTINE One_Column
  </code></pre>