如何测试两个阵列是否共享相同的内存块?

时间:2017-04-21 00:38:10

标签: julia

如何测试两个数组是否指向同一个内存块? 例如,我希望函数foo能够像这样工作:

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

我已对reinterpret(Float64,ar) === a进行了测试,但它返回false

对于SubArrays,这是通过parent(subofA) === A实现的,它返回true。但是我可以为重新解释的数组激发相同的结果。

2 个答案:

答案 0 :(得分:7)

reinterpret仅更改同一内存块的类型解释,因此解决方案是比较指针:foo(x,y) = pointer(x) == pointer(y)

答案 1 :(得分:4)

一个稍微强大的解决方案是:

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)

这仍然使用指针来比较Array,但它也会处理第一个元素偏移的SubArrays。

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

虽然仅仅比较pointer s会有一些假阴性,但这种方法会有一些误报。这种方法也适用于任何数组类型;某些数组不会实现指针,如果您尝试使用它会抛出错误。

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