# Fortran ccall variables persisting in the background

**URL:** <https://discourse.julialang.org/t/fortran-ccall-variables-persisting-in-the-background/53454>\
**Category:** General Usage\
**Tags:** question, ccall, fortran\
**Created:** [January 16, 2021, 8:20pm UTC](https://discourse.julialang.org/t/fortran-ccall-variables-persisting-in-the-background/53454 "2021-01-16T20:20:29Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![lamorton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lamorton/32/21115_2.png) [@lamorton](https://discourse.julialang.org/u/lamorton)\
**Post date:** [January 16, 2021, 8:20pm UTC](https://discourse.julialang.org/t/fortran-ccall-variables-persisting-in-the-background/53454/1 "2021-01-16T20:20:29Z")

</div>

I wrote the following Fortran wrapper around an existing Fortran library that defines some ‘global’ parameters that persist between subroutines. General idea is that `libfida` defines a subroutine `read_tables` that loads some atomic physics cross-sections from an HDF5 file, which is then used by other subroutines like `bb_cx_rates` here.

```julia
module cx_helper
    implicit none
    private
    public :: cx_matrix, cx_rates
    contains
    subroutine cx_matrix(velocity,nlevels,rates) bind(C,name="cx_matrix")!{{{
        use libfida, only : SimulationInputs,bb_cx_rates,read_tables, nlevs,inputs,impurity_charge
        use, intrinsic :: iso_c_binding, only: c_int, c_double
        implicit none
        real(c_double), intent(in) :: velocity
        integer, intent(in) :: nlevels
        real(c_double), dimension(nlevels,nlevels), intent(inout) :: rates !! catches the output from bb_cx_rates
        integer :: n_in !! incoming neutral energy level (principle quantum number)
        real(c_double), dimension(nlevels) :: denn !! density [cm^-3] of each energy state of neutrals
        real(c_double), dimension(3) :: vn = [0.0,0.0,0.0] !! cm/s x,y,z components of velocity of neutral
        real(c_double), parameter, dimension(3) :: vi = [0.0,0.0,0.0]!! velocity of ion
        if (nlevels .gt. nlevs) then
            print *,"nlevels must be less than ",nlevs
            stop
        endif 
        vn(1) = velocity
        impurity_charge = 6

        inputs%verbose = 1
        inputs%tables_file = '/Users/lmorton/Code/FIDASIM_lib/tables/atomic_tables.h5'
        inputs%calc_neutron = 0
        call read_tables
        do n_in=1,6
            denn = 0.0
            denn(n_in) = 1.0
            call bb_cx_rates(denn,vn,vi,rates(n_in,:))
        enddo
    end subroutine cx_matrix!}}}

```

The Julia wrapper then looks like:

```julia
function cx_matrix(velocity::Float64)
    nlevs = Int32(6) #Maximum is 6, but can be lower
    σ = Array{Float64,2}(undef,nlevs,nlevs)
    ccall((:cx_matrix, "./cx_helper.so"), Cvoid, (Ptr{Float64},Ref{Int32},Ptr{Float64}), Ref(velocity),Ref(nlevs),σ)
    return σ
end

```

This works OK the first time I call it, but the second time I crash the REPL:

```julia
At line 3767 of file fidasim.f90
Fortran runtime error: Attempting to allocate already allocated variable 'cross'

```

The line referenced looks like this:

```julia
subroutine read_atomic_cross(fid, grp, cross)
   ...
   allocate(cross%log_cross(cross%m_max,cross%n_max, cross%nenergy))

```

Basically, it looks like (much to my surprise) that the Fortran variables are persisting in memory outside the initial `ccall`. I assumed that the `ccall` invocation would destroy the entire Fortran runtime session prior to returning control to Julia, so that I would just need to re-invoke the `read_tables` subroutine each time. It’s handy to avoid that, but now I have more issues:

- How do I destroy the Fortran variables when I’m done with them, to avoid memory leakage?
- How do I test whether the variables are still alive, so I don’t allocate twice & crash the REPL?

More generally, I don’t have a very good sense for what’s happening under the hood when Julia calls a foreign function, and I’m not sure where to find info/documentation on that.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 16, 2021, 9:43pm UTC](https://discourse.julialang.org/t/fortran-ccall-variables-persisting-in-the-background/53454/2 "2021-01-16T21:43:27Z")

</div>

> [@lamorton](#):
>
> I assumed that the `ccall` invocation would destroy the entire Fortran runtime session

There is no separate “Fortran runtime session”. The Fortran code is running in the same process as Julia. It is no different than if you were calling your Fortran code multiple times from other Fortran code. (It is _not_ like launching a separate program.)

> [@lamorton](#):
>
> How do I destroy the Fortran variables when I’m done with them, to avoid memory leakage?

The same way as if you were calling your Fortran functions multiple times from Fortran. (It’s hard to say more without seeing the Fortran code that is allocating the `cross` cvariable that it is complaining about. But presumably you want the `deallocate` statement in Fortran?)

---

<div class="post-metadata">

**Author:** ![lamorton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lamorton/32/21115_2.png) [@lamorton](https://discourse.julialang.org/u/lamorton)\
**Post date:** [January 16, 2021, 11:57pm UTC](https://discourse.julialang.org/t/fortran-ccall-variables-persisting-in-the-background/53454/3 "2021-01-16T23:57:35Z")

</div>

Ahh, thank you for correcting my conceptual error! I was thinking that there was a separate process/program being spawned.

> But presumably you want the `deallocate` statement in Fortran?

OK, so Julia won’t know to deallocate those variables since Julia didn’t allocate them? And if I don’t do it with Fortran, then even when my Julia session ends, there will be memory tied up?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 17, 2021, 2:01pm UTC](https://discourse.julialang.org/t/fortran-ccall-variables-persisting-in-the-background/53454/4 "2021-01-17T14:01:03Z")

</div>

> [@lamorton](#):
>
> OK, so Julia won’t know to deallocate those variables since Julia didn’t allocate them?

As far as I know there is no standard API for accessing the Fortran `deallocate` statement from other languages. (In contrast, for memory allocated by `malloc` in C, it is perfectly possible to call [`free` in Julia](https://docs.julialang.org/en/v1/base/libc/#Base.Libc.free).) Regardless, there is no automatic garbage collection in Fortran — if you allocate global variables with `allocate`, you (not the language runtime) need to deallocate them if you want to reclaim the memory while the process is running.

> [@lamorton](#):
>
> And if I don’t do it with Fortran, then even when my Julia session ends, there will be memory tied up?

No, when a process exits, the operating system releases all memory assigned to that process, regardless of how it was allocated.
