Reputation: 1
In my code, I have memory problems due to the machine that I use, so I want to allocate the least memory possible during passing arguments. My example code:
program test
double precision, ALLOCATABLE :: arrayA(:)
allocate (arrayA(n))
call mySub (arrayA)
deallocate (arrayA)
stop
end
subroutine mySub ( arrayB )
double precision, ALLOCATABLE :: arrayB(:)
allocate (arrayB(n))
! operations with arrayB
return
end
In main program, I have to use the heap memory. I also want to use heap memory in my subrotuine. Acc to search I did, it gives running error ( Attempting to allocate already allocated array 'arrayb').
Therefore, my purposes are to use heap memory also in my subroutines, and to allocate the least memory possible during argument passing from program to subroutine like in the code above. Now, I think I do copy assignment and as I know, it is not good. I checked module, interface and contains blocks but it is not so clear which one is good to save some space in memory with allocatabel arrays. I appreciate any help fits into my purpose.
Upvotes: 0
Views: 1372
Reputation: 1
If a procedure has a dummy argument, that is an allocatable, then an explicit interface is required in any calling scope. You can provide that explicit interface, by putting an interface block, for your subroutine, inside the main program. A better alternative, is put the subroutine inside a module, and USE that module in the main program. The explicit interface is then automatically created.
Upvotes: 0
Reputation: 31
In Fortran (at least in Fortran 90 or former versions), it is not possible to allocate an array using a subroutine and return the allocated array to main program. In your case, you should not allocate the array in the subroutine. Thus your subroutine could be:
subroutine mySub ( arrayB )
double precision :: arrayB(:)
! operations with arrayB
return
end
Then you can pass any array that has the same rank as arrayB, but the actual argument must be already allocated in main, just as you did.
program test
double precision, ALLOCATABLE :: arrayA(:)
allocate (arrayA(n))
call mySub (arrayA)
deallocate (arrayA)
stop
end
Upvotes: 0
Reputation: 60113
You can't allocate the array again when it is already allocated. There is also no sense in doing so. Also, allocatable dummy arguments require explicit interface using modules or similar. But who knows how your actual code looks like.
What you want is to just pass it in a simple way as you had it originally
subroutine mySub ( arrayB, n )
integer :: n
double precision :: arrayB(n)
! operations with arrayB
That is just fine. No copy is made if you pass the contiguous array as you show it. Read about passing by reference. What's the difference between passing by reference vs. passing by value?
You can also use assumed shape arrays (:)
, but be careful, you need the explicit interface (best using modules).
Upvotes: 3