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.

+3


source to share


2 answers


reinterpret

changes only type of-the interpretation of the same memory block, so the solution is to compare pointers: foo(x,y) = pointer(x) == pointer(y)

.



+7


source


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

      

+4


source







All Articles