如何测试两个数组是否指向同一个内存块?
例如,我希望函数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
。但是我可以为重新解释的数组激发相同的结果。
答案 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