Vector of vectors access to undefined reference


#1

Hi Guys!!!
I am trying to create a vector of vectors since I need the data structure to have a fixed number of rows(6) but variable number of columns. And in each of the units of the data structure I want to store an instance of a structure. My code is:

struct abc
    a::Float64
    b::Float64
    c
end


k = Vector{Vector{abc}}(6);


for i = 1:6
   for j = 1:6
        aa, bb, cc = i+1, j+1, rand(3);
        instance = abc(aa, bb, cc);
        k[i][j] = instance;
    end
end

I’m getting this error:

UndefRefError: access to undefined reference
Stacktrace:
[1] getindex(::Array{Array{abc,1},1}, ::Int64) at ./array.jl:549
[2] macro expansion at ./In[7]:5 [inlined]
[3] anonymous at ./:?

Can you guys tell me what I am doing wrong? Thanks!


#3

Your k is created with 6 undefined values, so when you index into k[i][j] you won’t access a properly initialized array.

Just create the vector with fill, and then use the push! to append to the inner vector.

btw. semicolons aren’t needed in Julia

struct abc
    a::Float64
    b::Float64
    c
end

k = fill(Vector{abc}(),6)

for i = 1:6
   for j = 1:6
        aa, bb, cc = i+1, j+1, rand(3);
        instance = abc(aa, bb, cc);
        push!(k[i], instance);
    end
end

#4

Be wary of fill.
It will create a Vector with all 6 elements referring to the same empty Vector.
If you want independent vectors, you could create with a comprehension:

k = [ Vector{abc}() for i = 1:6 ]

#6

Hi @greg_plowman, thanks a lot for the help!

That works!

I have just one doubt. Actually I need to have variable number of columns for each of the rows. I will be storing an instance of the structure abc in each cell of the 2D structure but in the actual problem I need to calculate the number of columns in each iteration of the outer loop(based on the value of i). I tried:

kk = [ Vector{abc}() for i = 1:3 ]
for i = 1:3
    for j = 1:i+1
        aa, bb, cc = i+1, j+1, rand(3);
        instance = abc(aa, bb, cc);
        push!(kk[i], instance);
    end
end

I’m getting kk as:

3-element Array{Array{abc,1},1}:
abc[abc(2.0, 2.0, [0.750578, 0.158137, 0.664006]), abc(2.0, 3.0, [0.293539, 0.479623, 0.932276])]
abc[abc(3.0, 2.0, [0.701739, 0.411975, 0.719304]), abc(3.0, 3.0, [0.351443, 0.149604, 0.131821]), abc(3.0, 4.0, [0.780022, 0.281377, 0.924904])]
abc[abc(4.0, 2.0, [0.212862, 0.150822, 0.784564]), abc(4.0, 3.0, [0.880618, 0.752912, 0.634355]), abc(4.0, 4.0, [0.0175809, 0.388531, 0.882258]), abc(4.0, 5.0, [0.407847, 0.919263, 0.207803])]
which means each row is also of type abc. But I just need the cells of the datastructure to be of type abc not the whole row.
Can you please suggest what I should change? Thanks!


#7

I got it.

kk = [ Vector{Any}() for i = 1:3 ]

Thanks anyways!


#8

No, that’s just the way Julia displays it.
kk is a 3-element Array{Array{abc,1},1}, which means each of the 3 elements are of type Array{abc,1}.
You can check this by looking at an individual element, say kk[1].

For performance, it’s generally better to avoid abstract types (e.g. Any) for containers if possible.


#9

@greg_plowman, Thanks!
So

kk = [ Vector{abc}() for i = 1:3 ]

would give me a vector(kk) with 3 elements each of type Vector{abc}? On running I’m getting:

abc[]
abc[]
abc[]

#10

That’s how Julia usually displays vectors:
Type[x, y, z]
An empty vector displays as Type[]

Try typing abc[] at the REPL.

To further convince yourself, try at the REPL:

typeof(kk)
eltype(kk)

typeof(kk[1])
eltype(kk[1])

#11

Thanks!