pro normalpass

; this procedure passes variables the normal way
; in which copies of variables are passed to subroutines

; make variables
A = make_array(1000,1000,/integer,value=1)
B = make_array(1000,1000,/integer,value=2)
C = make_array(1000,1000,/integer,value=3)
D = make_array(1000,1000,/integer,value=4)

; and pass them
subroutine, A, B, C, D

end
;-----------------------

pro subroutine, A, B, C, D

; now there is one copy in subroutine memory, plus one in main memory

print, mean(A), mean(B), mean(C), mean(D)

end


;******************************************


pro commonpass

; this procedure passes A and B in one common block,
; C in another common block, and D normally.

; create common memory blocks
common ABblock, A, B
common Cblock, C

; make variables
A = make_array(1000,1000,/integer,value=1)
B = make_array(1000,1000,/integer,value=2)
C = make_array(1000,1000,/integer,value=3)
D = make_array(1000,1000,/integer,value=4)

; pass the variables to subroutine
subroutine, D

end
;------------------------------

pro subroutine, D

; this procedure accepts D normally, the others as common blocks

common ABblock, A, B
common Cblock, C

; there is now one copy of A,B, and C in common memory,
; but two of D: one in main memory and one in the subroutine memory

print, mean(A), mean(B), mean(C), mean(D)

end


;************************************************


pro pointerpass

; this subroutine converts A,B,C to pointer variables to pass,
; but passes D normally.

; make variables
A = make_array(1000,1000,/integer,value=1)
B = make_array(1000,1000,/integer,value=2)
C = make_array(1000,1000,/integer,value=3)
D = make_array(1000,1000,/integer,value=4)

; convert some to pointer variables
; i.e.: copy to heap memory and save the addresses
Aptr = ptr_new(A)
Bptr = ptr_new(B)
Cptr = ptr_new(C)
; Aptr etc are just addresses for heap memory
; save memory: discard original variables
A = 0 & B = 0 & C = 0

; pass to subroutine
subroutine, Aptr,Bptr,Cptr,D

end 

;--------------------------

pro subroutine, Aptr,Bptr,Cptr, D

; recieves and converts pointer variables and D
; we now have A, B, and C in pointer (heap) memory,
; but D is in both main and subroutine memory

; let's use Aptr and Bptr directly,
; but convert Cptr to C in regular memory

; copy C from heap memory into subroutine memory
; then delete it from heap memory so we only have one copy
C = *Cptr
ptr_free, Cptr  ; or else we still have C in heap memory

print, mean(*Aptr),mean(*Bptr), mean(C), mean(D)

; note that once this subroutine ends,
; A and B are in heap memory as Aptr and Bptr,
; C will no longer exist
; D will still have a copy in main memory

end