# Copying mutable structs without using deepcopy()

**URL:** <https://discourse.julialang.org/t/copying-mutable-structs-without-using-deepcopy/106648>\
**Category:** Performance\
**Tags:** question, mutable-structure, deepcopy\
**Created:** [November 23, 2023, 8:24pm UTC](https://discourse.julialang.org/t/copying-mutable-structs-without-using-deepcopy/106648 "2023-11-23T20:24:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![rolim.gustavo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rolim.gustavo/32/46941_2.png) [@rolim.gustavo](https://discourse.julialang.org/u/rolim.gustavo)\
**Post date:** [November 23, 2023, 8:24pm UTC](https://discourse.julialang.org/t/copying-mutable-structs-without-using-deepcopy/106648/1 "2023-11-23T20:24:59Z")

</div>

Dear colleagues,

I am working on an optimization problem where I have to group a permutation of jobs, which have some characteristics. A solution to this problem can be easily represented as a vector of vectors of a type Batch, where Batch is a mutable struct defined as follows:

```julia
mutable struct Batch
    Jobs::Vector{Int16}
    Size::Int16
    Family::Int8

    Batch() = new(Vector{Int16}[], 0, 0)
end

```

Therefore, a solution is represented as:

```julia
sol = Vector{Batch}[[] for i::Int8 in 1:m]

```

where m is a given parameter.

I have also a reference solution called `sol_ref` which is also a vector of vectors of type batch and size m. The inner vectors are allowed to have a different size.

During the execution of my program I often have to replace `sol` with `sol_ref` and vice-versa. However, I want to avoid using deepcopy(), since it is memory intensive. My idea was to delete all elements manually and then replace the inner elements of each vector iteratively:

```julia
function Replace_Solution(sol::Vector{Vector{Batch}}, sol_ref::Vector{Vector{Batch}}, m::Int8)
    #----- Replaces the current solution with new ones

    for i in 1:m
        empty!(sol[i])
        append!(sol[i], sol_ref[i])
    end
end

```

However, `Replace_Solution` often leads to errors since it is not guaranteeing separate memory allocations. I am looking for ways to efficiently update `sol` with the contents of `sol_ref`. Can anyone give my a perspective of why this is happening?

**OBS:** When I use deepcopy(), the algorithm runs fine.

---

<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:** [November 23, 2023, 10:19pm UTC](https://discourse.julialang.org/t/copying-mutable-structs-without-using-deepcopy/106648/3 "2023-11-23T22:19:10Z")

</div>

The issue is that the the mutable structures will copied (when using `append!`) by reference, such that they will reference the same structures (note that even if the structure was not mutable, having the mutable `Jobs` field in it would cause you issues of the same sort). Thus, you need to copy the values explicitly for all elements of the structure One way to do it is to define a function to copy the data between two instances of `Batch`, and then use that. For example, something like:

```julia-repl
julia> function copy_data!(target::Batch, source::Batch)
           target.Size = source.Size
           target.Family = source.Family
           target.Jobs .= source.Jobs
           return target
       end
copy_data! (generic function with 1 method)

```

to be used with:

```julia-repl
julia> function Replace_Solution!(sol::Vector{Vector{Batch}}, sol_ref::Vector{Vector{Batch}}, m)
           for i in eachindex(sol,sol_ref)
               copy_data!(sol[i], sol_ref[i])
           end
           return sol
       end
Replace_Solution (generic function with 1 method)

```

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [November 23, 2023, 10:25pm UTC](https://discourse.julialang.org/t/copying-mutable-structs-without-using-deepcopy/106648/4 "2023-11-23T22:25:22Z")

</div>

I wouldn’t call the function `copy_` if it doesn’t copy.

---

<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:** [November 23, 2023, 10:27pm UTC](https://discourse.julialang.org/t/copying-mutable-structs-without-using-deepcopy/106648/5 "2023-11-23T22:27:44Z")

</div>

It does copy the values of the fields, in the same sense that `x = 1; y = copy(x)` copies. But that’s why I named it `copy_data!`.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [November 24, 2023, 8:37am UTC](https://discourse.julialang.org/t/copying-mutable-structs-without-using-deepcopy/106648/6 "2023-11-24T08:37:30Z")

</div>

Does this “just work”?

```julia
help?> copy!
search: copy! copyto! circcopy! unsafe_copyto! replaceproperty! copy copysign

  copy!(dst, src) -> dst

  In-place copy of src into dst, discarding any pre-existing elements in dst.
  If dst and src are of the same type, dst == src should hold after the call.
  If dst and src are multidimensional arrays, they must have equal axes.

  See also copyto!.

  │ Julia 1.1
  │
  │ This method requires at least Julia 1.1. In Julia 1.0 this method
  │ is available from the Future standard library as Future.copy!.

```
