# Understanding how an array of structures works

**URL:** <https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011>\
**Category:** General Usage\
**Tags:** question, arrays, struct\
**Created:** [September 3, 2020, 2:59pm UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011 "2020-09-03T14:59:56Z")\
**Posts on this page:** 12\
**Page:** 2

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 5, 2020, 5:00pm UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/21 "2020-09-05T17:00:58Z")

</div>

> [@lmiq](#):
>
> Is there a deep reason for one not be able to get a pointer to an immutable object?

A pointer assumes that the object lies somewhere in memory which might not be true. The object might not be created at all.

> [@lmiq](#):
>
> Since I cannot modify the value of `i.x` , because it is immutable, I am not sure if `y[1]` is a pointer to `i` or if is a copy of `i` at this moment.

How can you tell the difference? If it is isbits it is stored inline. What you take out from the array can be a pointer or a copy or something, since its immutable it doesn’t matter.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 5, 2020, 5:23pm UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/22 "2020-09-05T17:23:57Z")

</div>

> [@kristoffer.carlsson](#):
>
> A pointer assumes that the object lies somewhere in memory which might not be true. The object might not be created at all.

Uhm… I cannot imagine an example of that, but I will try to figure that out. Only if the object is never used and the compiler makes the decision of not creating it, I don’t know.

EDIT: I understand that one case where it does make sense for an immutable object not to have pointer is, specifically, when it is part of a larger array which itself has one pointer. This makes sense.

> [@kristoffer.carlsson](#):
>
> How can you tell the difference? If it is isbits it is stored inline. What you take out from the array can be a pointer or a copy or something, since its immutable it doesn’t matter.

Clearly it doesn’t matter for the use of the data, but if it might be a pointer, that means that the vector `y` of the example is not contiguous in memory. I was reasoning that a vector of immutable structs is in principle allocated when it is created and, thus, possibly contiguous, while the vector of mutable types clearly isn’t.

(By the way: I found now this interest post that might be of interest of people reaching here: [http://schurkus.com/2018/01/09/mutability-and-performance-in-julia/](http://schurkus.com/2018/01/09/mutability-and-performance-in-julia/) - which made me think that the references to immutable objects in a vector may or may not be copies, and the compiler will decide that trying to optimize performance).

Ps. 2. : Thank you very much kristoffer.carlsson for even taking your time to read this… Julia has an interesting peculiarity that the people answering the questions here are so deeply involved in the language that even very simple questions frequently derive into deep discussions on more profound aspects of the language design.

---

<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:** [September 5, 2020, 6:01pm UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/23 "2020-09-05T18:01:47Z")

</div>

> [@lmiq](#):
>
> > [@kristoffer.carlsson](#):
> >
> > A pointer assumes that the object lies somewhere in memory which might not be true. The object might not be created at all.
> 
> Uhm… I cannot imagine an example of that, but I will try to figure that out. Only if the object is never used and the compiler makes the decision of not creating it, I don’t know.

For example, consider:

```julia
f(z) = 2z^2 - 3z + 2

```

and you call `f(3+4im)` — i.e. you pass a `Complex{Int}`, an immutable `struct` comprising its real and imaginary `Int` parts. The intermediate computations like `2z^2` are also `Complex{Int}` values, but the compiler never allocates a `struct` of them anywhere (either on the heap or on the stack) — instead, these computations are all inlined and the real and imaginary parts of all of the intermediate values are stored separately in CPU registers (which don’t have a pointer address).

(You can see this explicitly if you do `@code_native f(3+4im)` — only the `movq` instructions at the beginning and the end load/store explicit `Complex{Int}` values from/to memory for the input and final output values, respectively.)

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 5, 2020, 6:10pm UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/24 "2020-09-05T18:10:04Z")

</div>

> [@lmiq](#):
>
> Clearly it doesn’t matter for the use of the data, but if it might be a pointer, that means that the vector `y` of the example is not contiguous in memory.

I guess the question is what you mean with `y[i]`. Do you mean what is returned from calling it or what is stored at offset `i` in `y`?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 5, 2020, 6:11pm UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/25 "2020-09-05T18:11:07Z")

</div>

I meant what is stored in offest `i` in `y`

(although I have to be honest in that I only realize that there is a difference between these two things now).

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 5, 2020, 6:59pm UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/26 "2020-09-05T18:59:04Z")

</div>

Okay, what’s actually stored there (for `isbits` struct) is always the data itself. So `y[1] = i` would have to copy the data from `i` into `y[1]`.

---

<div class="post-metadata">

**Author:** ![rjmoses](https://avatars.discourse-cdn.com/v4/letter/r/90db22/32.png) [@rjmoses](https://discourse.julialang.org/u/rjmoses)\
**Post date:** [September 9, 2020, 9:36am UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/27 "2020-09-09T09:36:45Z")

</div>

So, getting back to my original issue: How does one go about creating a dense array of structures in julia?

(I’m looking for sequential memory assignments similar to a struct of structs in C)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 9, 2020, 9:42am UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/28 "2020-09-09T09:42:40Z")

</div>

Nothing special is required, `Array{T}(undef, dims)` should work like for all other types.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 9, 2020, 9:52am UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/29 "2020-09-09T09:52:56Z")

</div>

> [@Tamas\_Papp](#):
>
> should work like for all other types.

With the restriction that `T` has to be `isbitstype`.

---

<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:** [September 9, 2020, 10:40am UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/30 "2020-09-09T10:40:50Z")

</div>

You can verify yourself, for example:

```julia
julia> struct Bar
           a::Char
       end

julia> struct Foo
           w::Float64
           y::Int
           x::Tuple{Int32,UInt32}
           z::Bar
       end

julia> a = Array{Foo}(undef, 10);

julia> a[2]
Foo(6.90014562949905e-310, 37, (11, 0x00000000), Bar('\x3e\xa1\xcf\xd0'))

julia> unsafe_load(pointer(a), 2)
Foo(6.90014562949905e-310, 37, (11, 0x00000000), Bar('\x3e\xa1\xcf\xd0'))

julia> unsafe_load(pointer(a) + sizeof(Foo))
Foo(6.90014562949905e-310, 37, (11, 0x00000000), Bar('\x3e\xa1\xcf\xd0'))

julia> a[3]
Foo(2.4e-322, 3, (1050791888, 0x00007f05), Bar('\x00\x00\x00\x35'))

julia> unsafe_load(pointer(a), 3)
Foo(2.4e-322, 3, (1050791888, 0x00007f05), Bar('\x00\x00\x00\x35'))

julia> unsafe_load(pointer(a) + (3-1)*sizeof(Foo))
Foo(2.4e-322, 3, (1050791888, 0x00007f05), Bar('\x00\x00\x00\x35'))

```

---

<div class="post-metadata">

**Author:** ![Sharath\_Gururaj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sharath_gururaj/32/19647_2.png) [@Sharath\_Gururaj](https://discourse.julialang.org/u/Sharath_Gururaj)\
**Post date:** [October 31, 2021, 6:10pm UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/31 "2021-10-31T18:10:24Z")

</div>

Ok, I understand that if we want an array of mutable structs, the contiguous array will contain pointers to the structs. The struct itself is somewhere on the heap.

This can have performance implications due to the extra pointer lookup as well the resulting as non-sequential memory access.

Is it possible to have an array of mutable structures, but the structures are laid out contiguously in memory?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [October 31, 2021, 6:14pm UTC](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011/32 "2021-10-31T18:14:17Z")

</div>

> [@Sharath\_Gururaj](#):
>
> Is it possible to have an array of mutable structures, but the structures are laid out contiguously in memory?

Currently, no.

[Previous page](https://discourse.julialang.org/t/understanding-how-an-array-of-structures-works/46011.md?page=1)
