Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!

Allocatable array

cmc
New Contributor I
215 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
215 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

6 Replies
Steve_Lionel
Black Belt Retired Employee
215 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.

cmc
New Contributor I
215 Views

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

JohnNichols
Valued Contributor II
215 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 

 

Ferdinand_T_
New Contributor II
216 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

cmc
New Contributor I
215 Views

Thank you Ferdinand! It works now :)

\Carl

David_Billinghurst
New Contributor II
215 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

 

Reply