0

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.

Cagatay
  • 1
  • 4

3 Answers3

2

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).

Community
  • 1
  • 1
  • I will repeat what I understood to check. In order to use dynamic memory for 'arrayb', I need explicit interface, this is ok. When I pass the 'arrayA' wtih size of _n_ to the subroutine in yor code sample, I do not allocate another _n_ amount of memory space for 'arrayB' ? This part is not clear to me. Acc to URL example,I think that I send just sth like a pointer that indicates address of 'arrayA' and subroutine works with this indicator. This what I understood. – Cagatay Nov 10 '15 at 15:42
  • Why would you allocate a **new array** when you want to **avoid a copy**? You don't want another one! You want to work with the original one. The argument passing works the way that the called subroutine gets a reference and knows where the original array is and works directly with it. – Vladimir F Героям слава Nov 10 '15 at 15:45
  • ok now, it is clear for me. I was wondering whether I copy the array or not during passing the argument but now you made it clear for me. Thanks for the explanation. – Cagatay Nov 10 '15 at 15:53
0

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
rabbit
  • 21
  • 4
  • Well, yes, Fortran 90 doesn't have allocatable arguments, but Fortran 95 with TR-15581 does and all compilers I know support that, so who cares? And be careful, you really do need an explicit interface for the assumed shape array argument and you don't show it in your snippet. – Vladimir F Героям слава Nov 12 '15 at 19:44
0

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.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158