Fortran Fortran - passing unknown array to subroutine

Click For Summary
The discussion revolves around passing an allocatable array to a Fortran subroutine, where the user encounters issues with memory references and interface declarations. The user aims to define the size of the array within the subroutine and return it to the main program. Key points include the need for correct variable names in the interface block, as the user mistakenly declared different names for the parameters. It is emphasized that when passing arrays, the declaration must reflect their array nature (e.g., using "d1(:)" instead of "d1"). Additionally, the importance of allocating memory for the allocatable array before use is highlighted, with suggestions to use the SIZE intrinsic function to determine the necessary allocation size. There are recommendations to avoid interface blocks in favor of modules or the contains feature for better organization and reduced redundancy. Overall, the conversation underscores the correct syntax and structure necessary for handling allocatable arrays in Fortran.
hobmarcus
Messages
10
Reaction score
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
Just FYI, if you are going to be posting code, please learn to use the "code" tags so that it is much more readable.
 
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)
 
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)
 
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:
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.
 
Learn If you want to write code for Python Machine learning, AI Statistics/data analysis Scientific research Web application servers Some microcontrollers JavaScript/Node JS/TypeScript Web sites Web application servers C# Games (Unity) Consumer applications (Windows) Business applications C++ Games (Unreal Engine) Operating systems, device drivers Microcontrollers/embedded systems Consumer applications (Linux) Some more tips: Do not learn C++ (or any other dialect of C) as a...

Similar threads

  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 5 ·
Replies
5
Views
13K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 4 ·
Replies
4
Views
4K