Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
3 Views

Allocatable array

Jump to solution

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

Accepted Solutions
Highlighted
New Contributor II
3 Views

Quote:cmc wrote:

Jump to solution

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
Highlighted
Black Belt
3 Views

You've already done it. As a

Jump to solution

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.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Beginner
3 Views

It doesn't work. I get an

Jump to solution

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

0 Kudos
Highlighted
New Contributor I
3 Views

print *, shape(array)

Jump to solution

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
Highlighted
New Contributor II
4 Views

Quote:cmc wrote:

Jump to solution

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
Highlighted
Beginner
3 Views

Thank you Ferdinand! It works

Jump to solution

Thank you Ferdinand! It works now :)

\Carl

0 Kudos
Highlighted
New Contributor II
3 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