# Why am I copying?

In my program, I have two types of structs, one with a very longvector, and another that holds a view of a sub-part of the vector of another, reshaped to a matrix.

In principle this should work:

``````function reshapeView(vec, start, length, width)
return reshape((@view vec[start:(start + width*length - 1)]), length, width)
end

struct A
vec
end

struct B
mat
end

a = A(rand(100))

b = B(reshapeView(a.vec, 3, 3, 3))
``````

Now b holds a view to 9 elements of a.vec, starting at index 3, reshaped to a 3x3 matrix as expected. If I change something in a.vec, it is reflected in b.mat. However, if I now define

``````struct C{T,N}
arr::Array{T,N}
end

C(vec::Vector{T}) where T = C{T,2}(reshapeView(vec, 3, 3, 3))

c = C(a.vec)
``````

suddenly c holds a copy of the elements, instead of a view. Where am I implicitly copying?

In the implicit `convert(Array{T,N}, ...)` in the constructor of `C`. Note `typeof(r)` below.

``````julia> r = reshape(view(rand(9), :), 3, 3)
3×3 reshape(view(::Vector{Float64}, :), 3, 3) with eltype Float64:
0.466486  0.796616   0.138344
0.882214  0.651785   0.149842
0.744935  0.0729783  0.0731422

julia> convert(Matrix{Float64}, r)
3×3 Matrix{Float64}:
0.466486  0.796616   0.138344
0.882214  0.651785   0.149842
0.744935  0.0729783  0.0731422
``````
2 Likes

If you want to keep all the type information to specialise on and avoid the copy, use:

``````struct C{T,N,A<:AbstractArray{T,N}}
arr::A
end
``````

You should be able to just pass the array into the constructor without needing to specify `T` or `N`:

``````C(vec::Vector) = C(reshapeView(vec, 3, 3, 3))
``````
1 Like