Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Fortran - passing unknown array to subroutine

  1. Apr 11, 2015 #1
    Im trying to pass an unknown size of array to the subroutine. Then I will define the size of array in subroutine and pass it back to main program. I tried to use interface but the complier said invalid memory reference
    or Explicit interface required for ' ' at (1): allocatable argument
    . Any suggestions or helps? I would really appreciate for any advice/tips.
    Code (Fortran):
    program
    implicit none
    integer :: data_1(10)
    integer ::  data_2(9)
    integer, allocatable :: third_array(:)

    data_1= (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
    data_2 = (/ 3, 4, 5, 6, 7, 8, 9, 10,11 /)

    interface
    subroutine abc  (d1,d2,ta)
    implicit none
    integer, INTENT(IN) :: n1
    integer, INTENT(IN) :: n2
    integer, INTENT(OUT), allocatable :: ta(:)
    end subroutine abc
    end interface


    call abc (data_1,data_2, third_array)

    write(*,*) "third_array", third_array

    stop

    endprogram

    !-------------------------------------------------------------------------


    subroutine abc (d1,d2,ta)

    implicit none

    integer, INTENT(IN) :: d1
    integer, INTENT(IN) :: d2
    integer, INTENT(OUT), allocatable :: ta(:)
    integer :: i
    allocate(ta(19))
    do i=1,10
         ta(i)=d1(i)
    end do
    do i=11,19
         ta(i)=d1(i-10)
    end do
    return
    end subroutine abc
     
    Last edited: Apr 11, 2015
  2. jcsd
  3. Apr 11, 2015 #2

    phinds

    User Avatar
    Gold Member
    2016 Award

    Just FYI, if you are going to be posting code, please learn to use the "code" tags so that it is much more readable.
     
  4. Apr 11, 2015 #3

    Mark44

    Staff: Mentor

    Code (Fortran):
    subroutine abc  (d1,d2,ta)
    implicit none
    integer, INTENT(IN) :: n1
    integer, INTENT(IN) :: n2
    integer, INTENT(OUT), allocatable :: ta(:)
    end subroutine abc
    Your declarations for n1 and n2 don't agree with the formal parameters in your subroutine -- d1 and d2.

    The last time I wrote any fortran code was about 20 years ago, and I didn't get into any of the features of allocatable arrays. From current reading, though, what you need to do after declaring an array to be allocatable, is to actually allocate space to it, using ALLOCATE. You can determine how much space to allocate to your merge array by using the SIZE intrinsic function to get the size of each of the two arrays that will be merged.

    Since I am not knowledgeable about the mechanics of passing allocatable arrays to a subroutine, if I were doing this program, I would do all of the work in the main program, at least until I figured out how to work with allocatable arrays as parameters.

    I think the following would work, but I don't have a Fortran compiler, so haven't tested it.

    Code (Fortran):

    REAL, ALLOCATABLE :: Merged (:)  ! Rank-1 allocatable array

    Arr1Size = SIZE(Array1)
    Ary2Size = SIZE(Array2)
    ALLOCATE (Merged(Arr1Size + Arr2Size))
      . . .
    IF (ALLOCATED Merged)) DEALLOCATE (Merged)
     
  5. Apr 11, 2015 #4
    Yeah, part of the problem may be the interface with the incorrect variable names, not to mentioned that the local function variables were not declared correctly to accept arrays.

    But maybe the whole function call is an overkill:
    Code (Text):

    integer s1, s2
    s1 = size(data_1)
    s2 = size(data_2)
    allocate( third_array(s1+s2) )
    third_array(1:s1) = data_1(1:s1)
    third_array(s1+1:s1+s2) = data_2(1:s2)
     
     
  6. Apr 11, 2015 #5
    But is there a way for me to pass the third_array to the subroutine first, and then allocate it? because i wantto use do loop to find the common number of each data set and assign them into third array actually. It is not directly related to the size of d1,d2
     
    Last edited: Apr 11, 2015
  7. Apr 12, 2015 #6
    You are already passing the third_array just fine.

    Say, did you pick up the two pieces of feedback that Mark and I posted?
    1.- (From Mark) Your interface block is wrong...it lists d1 and d2 in the subroutine argument list but then it includes declaration for n1 and n2, instead.
    2.- (From me) In your interface and subroutine, if d1 and d2 are meant to accept array arguments, they need to reflect that in their declaration just like data_1 and data_2 do...i.e., you need "d1(:) ", instead of simply " d1 " ...the latter is just a scalar.
    3.- (one more) In your subroutine, you are using "d1" in both loops; I am sure the second instance was meant to be "d2".

    Additionally, interface blocks are to be included after all non-executable statement and before any executable...up above, you included the interface block after a couple of executable statements where you assign values to data_1 and data_2 arrays.

    Lastly, to eliminate one more source of errors and a lot of unnecessary redundancy, I would recommend to stop using interface blocks and start using modules or the contains feature. In this simple program of yours contains would do just fine and would spare you the interface block.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Fortran - passing unknown array to subroutine
Loading...