Deepcopy usage

In this code:

module MatrixOp

function func!(A, BB)
    BB[1][1,1] += 100
    A, BB...
end

func(A, B...) = func!(copy(A), deepcopy(B))

A = rand(1:10,3,3)
b = rand(1:10,3,1)
c = rand(1:10,3,1)

A2, b2, b3 = func(A,b,b)

@show b2
@show b3

end

why is b2 and b3 returned the same? I would assume deepcopy() would create individual copies for each of the elements of the B tuple. What am I missing?

Before the deepcopy, there is one array that is referred to two times in the (b, b) tuple. After the deepcopy there is one new array and the elements in the new tuple refers to that new array. You can think of the result of deepcopy as if you would serialize the object, and then deserialize it back. It does not mean you get a copy of the object for every reference to it.

2 Likes

This is exactly my problem with deepcopy. Wouldn’t serialization break the reference between individual bs in the (b, b) tuple making it a (b1, b2)?

Is my solution then:

func(A, B...) = func!(copy(A), map(copy,B))

which is a poor man’s one-level-deep copy?

No, because the resulting data structure from serialization / deserialization would then have very different properties from the original one. You want the result of deepcopy to give you something that behaves the same as what you had, but with no shared references to the original object.

The solution is probably to either:

  • Not create the aliased data structure to being with
  • Write something custom that does what you want for this case
2 Likes

That actually makes sense. I had a different mental model on what serialisation/deserialisation should do. It makes sense that all relationships and metadata on what do the bits mean are preserved while the actual bits are copied to a new location.

Thanks for your help.

2 Likes