Structure Usage

Hi so I am currently trying to create a structure I have included a condensed version of my structure that I am trying to create. The issue is that when I try and set the values of the fields in the structure they are all overwritten with the last value that I have set to the structure and I was wondering how I could stop this.

MAXBD=5
mutable struct BODYSTRUCTURE
    BODYNAME::String                      # Units: 'nd', Desc: 'Body Name'
end


mutable struct MULTIBODYSTRUCTURE
    BD::Array{BODYSTRUCTURE,1}
end

bd = BODYSTRUCTURE(
    " ",
    )

M = MULTIBODYSTRUCTURE(
    fill(bd, (MAXBD)),
)

M.BD[1].BODYNAME="first"
M.BD[2].BODYNAME="second"

This produces the following:

julia> M.BD[2].BODYNAME
"second"

julia> M.BD[1].BODYNAME
"second"

Instead of the desired:

julia> M.BD[2].BODYNAME
"first"

julia> M.BD[1].BODYNAME
"second"

I would greatly appreciate any assistance with this problem.

fill will re-use the same element multiple times, not make independent copies. Thus:

julia> tri = fill([1], 3) # the same array, 3 times
3-element Array{Array{Int64,1},1}:
 [1]
 [1]
 [1]

julia> push!(tri[1], 2) # mutate the sole inner array
2-element Array{Int64,1}:
 1
 2

julia> tri
3-element Array{Array{Int64,1},1}:
 [1, 2]
 [1, 2]
 [1, 2]

julia> tri[3] = [3,4,5]; # replace an element of the outer array

julia> tri
3-element Array{Array{Int64,1},1}:
 [1, 2]
 [1, 2]
 [3, 4, 5]
2 Likes

What @mcabbott said is right. The way this is often worked around is to use list comprehensions:

M = MULTIBODYSTRUCTURE(
    collect(deepcopy(bd) for i in 1:MAXBD)
)
1 Like

You should replace these lines by:

M.BD[1] = BODYSTRUCTURE("first")
M.BD[2] = BODYSTRUCTURE("second")

Also, it seems that in your case you want an uninitialized array. Thus you may replace

M = MULTIBODYSTRUCTURE(
    fill(bd, (MAXBD)),
)

by

M = MULTIBODYSTRUCTURE(
    Array{BODYSTRUCTURE,1}(undef, MAXBD),
)
1 Like