Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Allocatable array

cmc
New Contributor I
809 Views

Hi,

With reference to my previous post (https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/844545) I want to send this array out of the routine which reads the file. The problem is that the size of the array (file) can change, so the main routine does not know the size of the array before the file has been read. How do I declare the array in the two routines?

subroutine main(file_name)
    
    implicit none
    character(len=100), intent(in)      :: file_name
    real(8), allocatable                :: array(:,:)
    
    call file(file_name, array)

end subroutine

subroutine file(file_name, array)

    implicit none
    character(len=*), intent(in)        :: file_name
    real(8), allocatable, intent(out)   :: array(:,:)
    integer(2)                          :: n_rows, n_columns, i, j, io
  
    open    (unit = 1, file = file_name, status = 'old')
    read    (1,*) n_rows, n_columns
    allocate(array(n_rows, n_columns))
    read    (unit = 1, fmt = *, iostat = io) ((array(i,j), j = 1, n_columns), i = 1, n_rows)

end subroutine

Cheers,
Carl

0 Kudos
1 Solution
Ferdinand_T_
New Contributor II
809 Views

cmc wrote:

It doesn't work. I get an access violation error...

Without seeing the full program code, it is hard to guess what is going wrong; the snippets you show look fine to me.

If I had to guess, I'd suspect you do not have an explicit interface for the file subroutine -- note that allocatable (deferred-shape) arrays require explicit interfaces -- which can be solved by putting your subroutines into a module and using it in the program.

Kind regards, Ferdinand

View solution in original post

0 Kudos
6 Replies
Steve_Lionel
Honored Contributor III
809 Views

You've already done it. As a test, put after the call to file:

print *, shape(array)

You can use ubound(array,1) and ubound(array,2) to get the upper bounds of each dimension.

0 Kudos
cmc
New Contributor I
809 Views

It doesn't work. I get an access violation error...
 

0 Kudos
JohnNichols
Valued Contributor III
809 Views

print *, shape(array)

You can use ubound(array,1) and ubound(array,2) to get the upper bounds of each dimension.

you learn something new every day - perhaps - I did not know this 

 

0 Kudos
Ferdinand_T_
New Contributor II
810 Views

cmc wrote:

It doesn't work. I get an access violation error...

Without seeing the full program code, it is hard to guess what is going wrong; the snippets you show look fine to me.

If I had to guess, I'd suspect you do not have an explicit interface for the file subroutine -- note that allocatable (deferred-shape) arrays require explicit interfaces -- which can be solved by putting your subroutines into a module and using it in the program.

Kind regards, Ferdinand

0 Kudos
cmc
New Contributor I
809 Views

Thank you Ferdinand! It works now :)

\Carl

0 Kudos
David_Billinghurst
New Contributor III
809 Views

Carl,

I would be helpful if you provided the complete example.  The code fragments you posted do not tell the whole story.

Try this.  Putting the subroutine in a module and using it provides the interface to the calling routine.  This works with the data file from your other post.

io_4.f90

program io_4
  use read_m
  implicit none
  real(8), allocatable :: array(:,:)
  integer n_rows, n_columns

  call readit('file.dat',array)
  
  n_rows = ubound(array,1)
  n_columns = ubound(array,2)
  write(*,*) array(1,1), array(1,n_columns)
  write(*,*) array(n_rows,1), array(n_rows,n_columns)

end program

read_m.f90

module read_m

contains

  subroutine readit(file_name, array)
    implicit none
    character(len=*), intent(in) :: file_name
    real(8), allocatable, intent(out) :: array(:,:)
    integer n_rows, n_columns, i, j

    open(1,file=file_name,status='old')
    read(1,*) n_rows, n_columns
    allocate(array(n_rows, n_columns))
    read(1,*) ((array(i,j), j = 1, n_columns), i = 1, n_rows)
    close(1)

  end subroutine

end module

 

0 Kudos
Reply