# Pointers to structs

**URL:** https://discourse.julialang.org/t/pointers-to-structs/34629
**Category:** General Usage
**Created:** [February 14, 2020, 2:24pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629 "2020-02-14T14:24:18Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![rvignolo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rvignolo/32/33498_2.png) [@rvignolo](https://discourse.julialang.org/u/rvignolo)
#### Post date: [February 14, 2020, 2:24pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/1 "2020-02-14T14:24:18Z")

</div>

Hi all,

I am having trouble defining simple structs and I would like your help!

The main issue is how to define a pointer to a struct of type `Inner` inside a struct of type `Outer`. So, the first idea is pretty obvious and looks like:

```julia
struct Inner
  i::Int64
  j::Int64
end

struct Outer
  u::Inner
  w::Int64
end

```

However, this approach leads to an initialization of `Outer` that needs an initialization of `Inner`:

```julia
obj = Outer(Inner(1, 2), 3)

```

In my case, I would like to initialize `Outer` objects without knowing the parameters that initialize the `Inner` object. To do this, the first idea it comes to my mind is making `Outer` mutable and changing its `u` parameter type to include `Nothing`:

```julia
mutable struct Outer
  u::Union{Inner,Nothing}
  w::Int64
end

```

So now, we can initialize using:

```julia
obj = Outer(nothing, 3)

```

And change the value of the `Inner` parameter later (once we know its parameters):

```julia
obj.u = Inner(1, 2)

```

But those two changes that I had to do (i.e. make the struct mutable and include the `Nothing` type) don’t look elegant to me. I would rather prefer to use a similar approach than C: use a pointer to a struct `Inner` inside `Outer`. This pointer can point to `NULL` meaning that it was not initialized or it can point to a struct of type `Inner`.

How can I achieve such behavior? Remember, I would like to keep the Outer struct immutable.

Maybe, one idea is to use a `Vector`. So let’s try it:

```julia
struct Outer
  u::Vector{Inner}
  v::Int64
end

```

and initialize using:

```julia
obj = Outer(Vector{Inner}(undef, 0), 3)

```

or, equivalently:

```julia
obj = Outer(Inner[], 3)

```

Later, I can push! an element:

```julia
push!(obj.u, Inner(1,2))

```

Is this the correct approach or there is a better one? Please, we aware that using a `Vector{Inner}` for `u` achieves the behavior of a list in C.

Thanks in advance!  
Ramiro.

---

<div class="post-metadata">

### Author: ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)
#### Post date: [February 14, 2020, 2:58pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/2 "2020-02-14T14:58:57Z")

</div>

why not:

```julia
struct Inner
  i::Int64
  j::Int64
end

struct Outer
  u::Ref
  w::Int64
end

julia> a = Outer(Ref{Inner}(), 3)
Outer(Base.RefValue{Inner}(Inner(4, 778529616)), 3)

julia> a.u[] = Inner(1,2)
Inner(1, 2)

julia> a
Outer(Base.RefValue{Inner}(Inner(1, 2)), 3)

```

---

<div class="post-metadata">

### Author: ![rvignolo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rvignolo/32/33498_2.png) [@rvignolo](https://discourse.julialang.org/u/rvignolo)
#### Post date: [February 14, 2020, 3:11pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/3 "2020-02-14T15:11:07Z")

</div>

Yes, it seems to be a nice approach. I would only add the type of the reference:

```julia
struct Outer
  u::Ref{Inner}
  w::Int64
end

```

This way seems better because `u` cannot handle lists.

More ideas or insights are welcome!

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [February 14, 2020, 3:12pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/4 "2020-02-14T15:12:10Z")

</div>

Why not go all the way with genericity?

```julia
struct Outer{T}
  u::Ref{T}
  w::Int64
end

```

And of course the convenience method:

```julia
Outer(a::Ref{T}, b::Int64) where T = Outer{T}(a,b)
```

---

<div class="post-metadata">

### Author: ![rvignolo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rvignolo/32/33498_2.png) [@rvignolo](https://discourse.julialang.org/u/rvignolo)
#### Post date: [February 14, 2020, 3:22pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/5 "2020-02-14T15:22:49Z")

</div>

I think that using only `Ref` is like using a `void` pointer in C.

This pointer can point to `NULL` or to ANY other struct.

How can I achieve that this reference points to `NULL` or to structs of a given type (in this case, to `Inner`)?

I would like to initialize outer objects with `u` pointing to `nothing` and later make them point to `Inner` objects. This is because this way I can check if `u` is nothing, then it was not defined.

In my `Vector` example I can check that using the `lenght` of the vector.

In @Sukera example I cannot do it because I cannot change the type of the reference once an `Outer` object has been initialized.

Thanks!

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [February 14, 2020, 3:24pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/6 "2020-02-14T15:24:38Z")

</div>

Note that in Julia, structs of bitstypes are a bitstype, i.e. stored as a flat set of bits without a pointer. This is one of the reasons why it’s so efficient to use them vs standard objects! So that means that a struct of ints, or a struct of struct of ints, will not have a pointer.

---

<div class="post-metadata">

### Author: ![rvignolo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rvignolo/32/33498_2.png) [@rvignolo](https://discourse.julialang.org/u/rvignolo)
#### Post date: [February 14, 2020, 3:27pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/7 "2020-02-14T15:27:33Z")

</div>

This is really useful! Great!

For the porpoise of this example, let’s assume `Inner` is way more general and it does not include only Ints.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [February 14, 2020, 3:30pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/8 "2020-02-14T15:30:42Z")

</div>

Well, you can always do

```julia
Outer(Ref{Union{<all the types you need>}}(), ...)

```

no?

Having an unlimited number of possible values there will lead to slower code because dynamic dispatch will be necessary. You could maybe use `u::Any`, but I doubt you want to dispatch everytime you need `u` 🙂 What core problem are you trying to solve? Maybe there’s a more julian way of doing this.

---

<div class="post-metadata">

### Author: ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)
#### Post date: [February 14, 2020, 4:09pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/9 "2020-02-14T16:09:55Z")

</div>

Note that this works:

```julia
struct Inner
  i::Int64
  j::Int64
end

mutable struct Outer
  u::Inner
  w::Int64
  function Outer(w::Int64) 
    o = new()
    o.w = w
    o
  end
end

```

Then

```julia
julia> obj = Outer(3) # Inner is random junk
Outer(Inner(0, 0), 3)

julia> obj.u = Inner(1,2);

julia> obj
Outer(Inner(1, 2), 3)

```

But you can’t check whether `Inner` has been defined this way. You’d need to add a flag, or do the union approach.  
If Inner weren’t bitstype, it would show up as `undef`, and you could query whether or not it is defined with `isdefined`.

But if it’s all BitsTypes, you may as well make `Outer` a `struct` (not mutable), and construct new ones as needed. This will probably be the fastest of the options.

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [February 14, 2020, 4:55pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/10 "2020-02-14T16:55:55Z")

</div>

You could take a functional approach, leaving everything immutable, and use `@set` from Setfield.jl to rebuild the structs when you need to change something. You can even change the type of fields in the inner struct and Setfield will just rebuild the whole thing. And you get to keep the performance of immutable structs.

---

<div class="post-metadata">

### Author: ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)
#### Post date: [February 14, 2020, 6:33pm UTC](https://discourse.julialang.org/t/pointers-to-structs/34629/11 "2020-02-14T18:33:29Z")

</div>

Just a note, but I don’t know the relevance of this in actual code:

`Ref{T}` is still an abstract type. The two possible concrete types `A` where `A<:Ref{T}` are `Base.RefValue{T}` and `Base.RefArray{T}`.  
So, in order for your `Outer` type to be concretely typed it should be defined as:

```julia
struct Outer
    u::Base.RefValue{Inner}
    w::Int64
end

```
