How can I check if two arrays have the same block of memory?
How can I check if two arrays point to the same block of memory? For example, I need a function foo
that will work like this:
a = rand(10) # Float64 array with 10 elements
b = copy(a) # b == a is true, but b === a is false
ar = reinterpret(Float32,a)
foo(ar,a) # I'd like this to return true
foo(reinterpret(Float64,ar),b) # I'd like this to return false, even if reinterpret(Float64,ar) == b
I have tested reinterpret(Float64,ar) === a
but it returns false
.
For SubArrays, this is achieved with a parent(subofA) === A
return true
. But I could provoke the same results for reinterpreted arrays.
source to share
A slightly more reliable solution:
data_id(A::StridedArray) = A === parent(A) ? UInt(pointer(A)) : data_id(parent(A))
data_id(A::AbstractArray) = A === parent(A) ? object_id(A) : data_id(parent(A))
might_share_data(A, B) = data_id(A) == data_id(B)
This still uses pointers for comparison Array
, but also handles SubArrays where the first element is offset.
julia> A = rand(3,4)
B = view(A, 2:3, 2:3);
julia> pointer(A) == pointer(B)
false
julia> might_share_data(A, B)
true
While only the comparison pointer
will have some false negatives, this method will have some false positives. This approach will also work for any type of array; some arrays do not implement a pointer and will throw an error if you try to use it.
julia> C = view(A, [2,3], [2,3]);
julia> pointer(C)
ERROR: conversion to pointer not defined for SubArray{Float64,2,Array{Float64,2},Tuple{Array{Int64,1},Array{Int64,1}},false}
in pointer(::SubArray{Float64,2,Array{Float64,2},Tuple{Array{Int64,1},Array{Int64,1}},false}) at ./abstractarray.jl:736
julia> might_share_data(A, C)
true
source to share