# Interpreting raw memory as a vector of unions

**URL:** <https://discourse.julialang.org/t/interpreting-raw-memory-as-a-vector-of-unions/61128>\
**Category:** General Usage\
**Created:** [May 14, 2021, 7:03am UTC](https://discourse.julialang.org/t/interpreting-raw-memory-as-a-vector-of-unions/61128 "2021-05-14T07:03:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sheemon7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sheemon7/32/10277_2.png) [@Sheemon7](https://discourse.julialang.org/u/Sheemon7)\
**Post date:** [May 14, 2021, 7:03am UTC](https://discourse.julialang.org/t/interpreting-raw-memory-as-a-vector-of-unions/61128/1 "2021-05-14T07:03:20Z")

</div>

To avoid excessive allocation & garbage collection for performance critical applications, I sometimes use the following approach (simplified):

```julia
buffer = pointer(Vector{UInt8}(undef, 100))
function alloc(::Type{T}, n, offset) where T
    size = n * sizeof(T)
    ptr = buffer + offset
    unsafe_wrap(Vector{T}, convert(Ptr{T}, ptr), n), offset + size
end

julia> offset = 0
0

julia> a, offset = alloc(Int, 2, offset)
([4627565936, 4627565936], 16)

julia> a, offset = alloc(Float64, 2, offset)
([2.2864006326e-314, 2.394940531e-314], 32)

```

This works for any `isbits` type. Is it possible directly interpret a chunk of memory as a vector of `isbitsunion` elements, .e.g. `Union{Nothing, Int64}`? I couldn’t find anything in docs and `unsafe_wrap` doesn’t work either:

```julia
julia> a = unsafe_wrap(Vector{Int64}, pointer([1,2,3]), 3)
3-element Vector{Int64}:
 1
 2
 3

julia> a = unsafe_wrap(Vector{Union{Nothing, Int64}}, pointer([1,2,nothing]), 3)
ERROR: ArgumentError: unsafe_wrap: unspecified layout for union element type
Stacktrace:
 [1] #unsafe_wrap#81
   @ ./pointer.jl:89 [inlined]
 [2] unsafe_wrap(::Type{Vector{Union{Nothing, Int64}}}, p::Ptr{Union{Nothing, Int64}}, d::Int64)
   @ Base ./pointer.jl:89
 [3] top-level scope
   @ REPL[76]:1

```

---

<div class="post-metadata">

**Author:** ![baumgold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baumgold/32/28576_2.png) [@baumgold](https://discourse.julialang.org/u/baumgold)\
**Post date:** [February 22, 2022, 3:35pm UTC](https://discourse.julialang.org/t/interpreting-raw-memory-as-a-vector-of-unions/61128/2 "2022-02-22T15:35:15Z")

</div>

@Sheemon7 - did you ever find a solution to this problem? Thanks.

---

<div class="post-metadata">

**Author:** ![Sheemon7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sheemon7/32/10277_2.png) [@Sheemon7](https://discourse.julialang.org/u/Sheemon7)\
**Post date:** [February 22, 2022, 3:50pm UTC](https://discourse.julialang.org/t/interpreting-raw-memory-as-a-vector-of-unions/61128/3 "2022-02-22T15:50:20Z")

</div>

No, unfortunately not ☹

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [February 22, 2022, 4:43pm UTC](https://discourse.julialang.org/t/interpreting-raw-memory-as-a-vector-of-unions/61128/4 "2022-02-22T16:43:11Z")

</div>

How should this work? What value would indicate the position has `nothing` and how it would not be a valid `Int64` value?

---

<div class="post-metadata">

**Author:** ![baumgold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baumgold/32/28576_2.png) [@baumgold](https://discourse.julialang.org/u/baumgold)\
**Post date:** [February 23, 2022, 1:24am UTC](https://discourse.julialang.org/t/interpreting-raw-memory-as-a-vector-of-unions/61128/5 "2022-02-23T01:24:00Z")

</div>

`Union{Nothing, Int64}` is not isbitstype but it _is_ isbitsunion. Thanks to the [isbits union optimizations](https://docs.julialang.org/en/v1/devdocs/isbitsunionarrays) this type can be stored inline in an array. It can’t quite be unsafe\_wrap’d as desired due to the extra “type tag array” but it can still pretty much work:

```julia
julia> buffer = resize!(Vector{Union{Nothing, Int64}}(), 100)
 nothing
 ...

julia> function alloc(::Type{Union{Nothing,Int64}}, n, offset)
           view(buffer, UnitRange(offset, offset + n - 1)), offset + n
       end
alloc (generic function with 1 method)

julia> alloc(Union{Nothing,Int64}, 2, 1)
(Union{Nothing, Int64}[nothing, nothing], 3)

```
