2017-04-21 59 views
3

如何测试两个数组是否指向相同的内存块? 例如,我要一个功能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

对于子数组,这通过0​​来实现,其返回true。但是我可以为重新解释的数组激发相同的结果。

回答

7

reinterpret只改变同一个内存块的类型解释,所以解决的办法是比较指针:foo(x,y) = pointer(x) == pointer(y)

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,但它也将处理子数组第一个元素被抵消。

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旨意有一定的假阴性,这种方法有一定的假阳性。这种方法也适用于任何数组类型;有些数组不会实现指针,如果您尝试使用它,会引发错误。

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 
+2

这很复杂,我们真的需要一个函数来为你做这件事。 – StefanKarpinski

相关问题