Home > database >  Working with an array of structs in Julia
Working with an array of structs in Julia

Time:11-01

I have a mutable struct defined in Julia, when I am unable to store data inside it. My struct is as follows:

mutable struct MPData{T}
    MPType::Char
    ConstModelType::Char
    MPCoords::Array{T}
    MPVol::T
    MPInitVol::T
    MPMass::T
    MPNodes::Array{UInt32}
    MPEls::Array{UInt32}
    NumStiffMatEntries::UInt32
    BasisFns::Array{T}
    BasisFnsDerivs::Array{T}
    PrevDefGrad::Array{T}
    CurrentDefGrad::Array{T}
    CauchyStress::Vector{T}
    PrevElasticStrain::Vector{T}
    CurrentElasticStrain::Vector{T}
    MatConsts::MatParams
    PointForces::Array{T}
    Displacement::Array{T}
end

The Initialization of the Array of the struct is as below: MPDataArray = Array{MPData{Float32},1}(undef, TotalNumMP) where TotalNumMP is the length of the array. But, when I try to actually populate the struct with data I am getting the error LoadError: UndefRefError: access to undefined reference. The code for populating the struct is:

for MPNum in 1:TotalNumMP
     MPDataArray[MPNum].MPType = 'M'
end

What am I doing wrong here?

CodePudding user response:

You created an array with your massive struct as its element type, but no actual instances of the struct were created to fill the array. That's called an uninitialized array, indicated by the undef.

If the struct was immutable and uses no pointers (isbitstype), you could have still indexed the array, but all the values would be random garbage.

However, you had a mutable struct which necessarily uses a pointer, so it was not an isbitstype. In that case, Julia does not allow you to access that element as if there were a struct there (MPDataArray[MPNum]), because otherwise you would have a dangling pointer, something so dangerous they won't even let you have it as random garbage. The only thing you're allowed to do with an uninitialized element is to initialize it i.e. assign a proper struct instance:

MPDataArray[MPNum] = MPData(...)

It appears that you want to make an array with actual instances, then modify it. In that case you should define a way to make a dummy value, like:

Base.zero(::Type{MPData{T}}) where T = MPData(...)

Then you can make a fully initialized array of dummy values with:

zeros(MPData{T}, TotalNumMP)
  • Related