2017-04-21 65 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

相關問題