# Checking if a vector of structs is contiguous in memory

Hi,

So I have an vector of tuples of floats, i.e.: `Array{Tuple{Float64,Float64},1}()`. I know that tuples are immutables and so theoretically this array should be contiguous in memory and there should be no pointers in the vector or the tuples. Is this true? And more generally is there a way that I can check whether is type in contiguous in memory or whether it contains pointers in it?

Thanks.

2 Likes

You could try something like that:

``````x = Array{Tuple{Float64,Float64},1}()
push!(x,(1.,1.),(2.,2.),(3.,3.))

ptr = pointer(x)
offset = sizeof(x)
``````
2 Likes

You can get a pointer to the n-th element of a vector `v` using `pointer(v,n)`. The difference between two consecutive indices gives accordingly the size occupied by one element in the vector. You can then compare that to the actual size of the elements of `v`:

``````v = Vector( [(1., 2., 3.), (4., 5., 6.), (7., 8., 9.)] )
d = Signed(pointer(v,2) - pointer(v,1))      # = 24
d == sizeof(eltype(v)) ? "contiguous" : "non-contiguous or padded"
# prints "contiguous"
``````

If you work with `Array` then the above should always hold if `eltype(v)` is a bitstype; check with `Base.isbits(eltype(v))`. For other element types or `AbstractArray` in general, it is not necessarily the case.
Also, if `v` were a `SubArray`, you could directly use `Base.iscontiguous(v)`, which unfortunately is not implemented for plain `Array` types…

``````s = SubArray( v, (1:3,))   # make a subarray from `v`
Base.iscontiguous(s)       # returns true
``````

This does not tell you if there’s indirection.

If you want to programatically check if an `Array` has no indirection, `isbits(eltype(v))` should tell you. If you want to verify/see it yourself, you can use the `unsafe_load` in @jonathanBieler’s answer to check. Note that `d == sizeof(eltype(v))` is wrong since it gives your wrong answer for mutable struct of the right size.

True. Further, `d == sizeof(eltype(v))` would give a false positive if `eltype(v)` were mutable and `sizeof(eltype(v))` were of size of a pointer… A generalization of `Base.iscontigous` might indeed be quite useful.

`Base.iscontiguous` is not meant for this. It’s only for indexing.

Looks like `isbits(eltype(x))` works for this particular case and the `unsafe_load` method works in general. Thanks for the prompt answers everyone.

Just to be clear that you should not use this in real code. You can get a segfault if you made the wrong guess.

2 Likes

Oh yes I got that. I just wanted to check that this data structure is continguous to make sure it won’t be too slow.

I love the manually digging through memory approach. And for those who want an easier way, @tkf told me about `Base.allocatedinline` which does precisely this. When will a vector of structs be contiguous in memory? - #2 by tkf

If I’m not mistaken, it should be `isbitstype(eltype(x))` instead of `isbits(eltype(x))`.

1 Like