# How to keep a reference for C structure to avoid GC?

**URL:** https://discourse.julialang.org/t/how-to-keep-a-reference-for-c-structure-to-avoid-gc/9310
**Category:** General Usage
**Created:** [February 25, 2018, 7:10am UTC](https://discourse.julialang.org/t/how-to-keep-a-reference-for-c-structure-to-avoid-gc/9310 "2018-02-25T07:10:06Z")
**Posts on this page:** 6
**Page:** 2

<div class="post-metadata">

### Author: ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)
#### Post date: [November 6, 2019, 12:52am UTC](https://discourse.julialang.org/t/how-to-keep-a-reference-for-c-structure-to-avoid-gc/9310/21 "2019-11-06T00:52:04Z")

</div>

@yuyichao, I’d take the opportunity here to ask a related question:

```julia
struct A
   x::Vector{Int}
end
struct B
   ptrA::Ptr{A}
end
a = A([1,2,3])
b = B(pointer_from_objref(Ref(a))

```

I need to pass `b` (or its `Ptr{B}`) to `ccall`. If I understand correctly I should wrap functions getting `b` with `GC.@preserve`:

```julia
GC.@preserve a begin
   some_function_ccalling_mayyybeee(b)
end

```

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [November 6, 2019, 2:17am UTC](https://discourse.julialang.org/t/how-to-keep-a-reference-for-c-structure-to-avoid-gc/9310/22 "2019-11-06T02:17:43Z")

</div>

> [@abulak](#):
>
> ```julia
> b = B(pointer_from_objref(Ref(a))
> 
> ```

You are getting a garbage pointer here. If you want `ptrA` to point to `A` then you need to copy what `ccall(... (Ref{A},), a::A)` does. i.e. `v = cconvert(Ref{A}, a); GC.@preserve v begin b = B(unsafe_convert(Ref{A}, v)) end`

---

<div class="post-metadata">

### Author: ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)
#### Post date: [November 6, 2019, 10:50am UTC](https://discourse.julialang.org/t/how-to-keep-a-reference-for-c-structure-to-avoid-gc/9310/23 "2019-11-06T10:50:48Z")

</div>

yes, that was a contrived example (which was obviously wrong), thanks for clarification!

---

<div class="post-metadata">

### Author: ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)
#### Post date: [November 6, 2019, 4:42pm UTC](https://discourse.julialang.org/t/how-to-keep-a-reference-for-c-structure-to-avoid-gc/9310/24 "2019-11-06T16:42:39Z")

</div>

After a while of investigation two more questions:

- ` Ref(a::A) → Base.RefValue(a::A) → Base.RefValue{A}(a)`, whereas `Base.cconvert(Ref{A}, a) → convert(Ref{A}, a) → Base.RefValue{A}(a)`. Why do you suggest `ra = Base.cconvert(Ref{A}, a)` instead of simple `ra = Ref(a)`?

- On the other hand `Base.unsafe_convert(Ref{A}, ra) → Base.unsafe_convert(Ptr{A}, v) → black_magic`😉 so `Base.unsafe_convert(Ref{A}, ra)` leads to the correct thing, but why is this encouraged instead of more direct `Base.unsafe_convert(Ptr{A},ra)`?

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [November 6, 2019, 5:08pm UTC](https://discourse.julialang.org/t/how-to-keep-a-reference-for-c-structure-to-avoid-gc/9310/25 "2019-11-06T17:08:13Z")

</div>

Because there are two way to do this,

1. You know how to do the black magic part and then you can just write `ra = Ref(a)` and do the black magic part yourself. That’s totally fine.
2. You don’t know how to do the black magic part and then you should use the generic mechanism setup for this, i.e. matching pair of `cconvert` and `unsafe_convert`.

Either way is fine, However, you must use `unsafe_convert` and `cconvert` in matching pair, the type and value for the intermediate result (i.e. return value of `cconvert`) is completely implementation detail and isn’t something you should rely on (unless you implemented it yourself, of course).

* * *

Therefore,

> [@abulak](#):
>
> `Base.cconvert(Ref{A}, a) → convert(Ref{A}, a) → Base.RefValue{A}(a)` .

and

> [@abulak](#):
>
> `Base.unsafe_convert(Ref{A}, ra) → Base.unsafe_convert(Ptr{A}, v)`

Are both looking at implementation detail.

* * *

> [@abulak](#):
>
> Why do you suggest `ra = Base.cconvert(Ref{A}, a)` instead of simple `ra = Ref(a)` ?

This is fine as long as you don’t call **any** `unsafe_convert` on it.

* * *

> [@abulak](#):
>
> - `Base.unsafe_convert(Ref{A}, ra)` leads to the correct thing, but why is this encouraged instead of more direct `Base.unsafe_convert(Ptr{A},ra)` ?

And this would be wrong if you use `cconvert` on `Ref{A}`. If you call `Base.unsafe_convert(Ptr{A},ra)`, `ra` **must** be the return value from a `Base.cconvert(Ptr{A}, ...)` (see below)

* * *

Now what I said above is not the only way to use matching `cconvert` and `unsafe_convert`. Converting to `Ptr{A}` is also allowed but you just won’t get it from a normal object off type `A`. You need to replace it with `Ref(a)`. In another word, it is valid and well supported too if you replace `ra = cconvert(Ref{A}, a)` with `ra = cconvert(Ptr{A}, Ref(a))` and `unsafe_convert(Ref{A}, ra)` with `unsafe_convert(Ptr{A}, ra)`.

---

<div class="post-metadata">

### Author: ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)
#### Post date: [November 6, 2019, 5:14pm UTC](https://discourse.julialang.org/t/how-to-keep-a-reference-for-c-structure-to-avoid-gc/9310/26 "2019-11-06T17:14:16Z")

</div>

That was very enlightening, thanks a lot!

[Previous page](https://discourse.julialang.org/t/how-to-keep-a-reference-for-c-structure-to-avoid-gc/9310.md?page=1)
