Hello, I have a question about a very unexpected behavior I encountered, I’d like an ELI5.
Why does this:
vi = fill(Int[], 5)
vi[2] = [5,6]
push!(vi[3], 9)
result in
[9]
[5, 6]
[9]
[9]
[9]
instead of in
[]
[5, 6]
[9]
[]
[]
?
While we’re at it, why was the [5, 6] part left unchanged, unlike all the other elements?
BTW, my intention was to use a dynamic data structure consisting of n (determined at run time) independent dynamically created arrays, what’s the right way to do this (in case I’m doing it wrong)?
The reason is order of operations. This is a common trip-up. In the expression:
fill(Int[], 5)
First the the array Int[] is created, then the “outer” (5-element) array is created, and each element of that array references the empty Int[] array. These are all references to the same array, so when you modify one of them (by pushing) you modify them all.
It breaks down like this:
x = Int[]
vi = [x for _ in 1:5] # vi == [[], [], [], [], []]
push!(x, 1) # vi == [[1], [1], [1], [1], [1]]
vi[2] = [5, 6] # vi == [[1], [5, 6], [1], [1], [1]]