Fortran - passing unknown array to subroutine

In summary, the complier said invalid memory reference or Explicit interface required for ' ' at (1): allocatable argument.
  • #1
hobmarcus
10
0
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.
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 interfacecall 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:
Technology news on Phys.org
  • #2
Just FYI, if you are going to be posting code, please learn to use the "code" tags so that it is much more readable.
 
  • #3
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.

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

Arr1Size = SIZE(Array1)
Ary2Size = SIZE(Array2)
ALLOCATE (Merged(Arr1Size + Arr2Size))
  . . .
IF (ALLOCATED Merged)) DEALLOCATE (Merged)
 
  • #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:
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)
 
  • #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:
  • #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.
 

1. Can I pass an unknown array to a Fortran subroutine?

Yes, you can pass an unknown array to a Fortran subroutine by using the "assumed shape" or "assumed size" array declaration. This allows the array to be of any size and shape, and the subroutine can access its elements without knowing the exact size or shape beforehand.

2. How do I declare an assumed shape array in Fortran?

To declare an assumed shape array, use the colon (:) operator in the array declaration. For example, "real, dimension(:) :: my_array" declares an assumed shape real array called "my_array".

3. Can I modify an assumed shape array in a Fortran subroutine?

Yes, you can modify an assumed shape array in a Fortran subroutine by using the "intent(inout)" or "intent(out)" attribute in the subroutine declaration. This allows the subroutine to both read from and write to the array.

4. How do I access elements of an assumed shape array in a Fortran subroutine?

To access elements of an assumed shape array in a Fortran subroutine, use the same syntax as you would for a regular array. For example, if the assumed shape array is declared as "real, dimension(:) :: my_array", then the elements can be accessed using "my_array(i)", where "i" is the index of the element.

5. Are there any limitations to using assumed shape arrays in Fortran subroutines?

One limitation of assumed shape arrays in Fortran is that they cannot be used with assumed size or assumed rank arrays. Additionally, the array must be contiguous in memory, meaning that its elements must be stored in consecutive memory locations. Finally, if the array is passed as an argument to another subroutine, it must also be declared as assumed shape in that subroutine.

Similar threads

  • Programming and Computer Science
Replies
20
Views
1K
  • Programming and Computer Science
Replies
8
Views
1K
  • Programming and Computer Science
Replies
4
Views
621
  • Programming and Computer Science
Replies
3
Views
1K
  • Programming and Computer Science
Replies
4
Views
2K
  • Programming and Computer Science
Replies
2
Views
1K
  • Programming and Computer Science
Replies
8
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
1K
  • Programming and Computer Science
Replies
4
Views
1K
  • Programming and Computer Science
Replies
5
Views
12K
Back
Top