Pointers 在移动Vec时,我是否可以(不安全地)握住指向Vec元素的指针?
我正在实现一个算法,为了保持所需的时间复杂度,我希望在移动Pointers 在移动Vec时,我是否可以(不安全地)握住指向Vec元素的指针?,pointers,rust,move-semantics,unsafe,vec,Pointers,Rust,Move Semantics,Unsafe,Vec,我正在实现一个算法,为了保持所需的时间复杂度,我希望在移动Vec时保持指向Vec元素的指针 具体来说,是这样的: fn main() { let mut v: Vec<usize> = vec![1, 2, 3]; let ptr: *mut usize = &mut v[1] as *mut usize; let mut u: Vec<usize> = v; assert!(ptr == &mut u[1] as *mut
Vec
时保持指向Vec
元素的指针
具体来说,是这样的:
fn main() {
let mut v: Vec<usize> = vec![1, 2, 3];
let ptr: *mut usize = &mut v[1] as *mut usize;
let mut u: Vec<usize> = v;
assert!(ptr == &mut u[1] as *mut usize);
println!("{}", unsafe { *ptr });
}
fn main() {
let mut v: Vec<usize> = vec![1, 2, 3];
let ptr: *mut usize = &mut v[1] as *mut usize;
let mut u: Vec<usize> = v;
assert!(ptr == &mut u[1] as *mut usize);
// I copied this from Stack Overflow without reading the surrounding prose
println!("{}", unsafe { *ptr });
}
fn main(){
让mut v:Vec=Vec![1,2,3];
让ptr:*mut usize=&mut v[1]作为*mut usize;
设mut u:Vec=v;
断言!(ptr==&mut u[1]为*mut usize);
println!(“{}”,不安全的{*ptr});
}
实际代码更为复杂,并且涉及一个树状数据结构,其中每个顶点都拥有一个子节点的Vec
。这里我不是问编码风格,但我的问题是,是否可以依赖这些代码来完成我认为它所做的事情
由于
Vec
必须将其内容保存在堆上,而moves在Rust中相当于memcpy
,因此我认为Vec
是可移动的这一事实意味着我的代码是可靠的(即不是未定义的行为)。这是否正确?您可以这样做:
fn main() {
let mut v: Vec<usize> = vec![1, 2, 3];
let ptr: *mut usize = &mut v[1] as *mut usize;
let mut u: Vec<usize> = v;
assert!(ptr == &mut u[1] as *mut usize);
println!("{}", unsafe { *ptr });
}
fn main() {
let mut v: Vec<usize> = vec![1, 2, 3];
let ptr: *mut usize = &mut v[1] as *mut usize;
let mut u: Vec<usize> = v;
assert!(ptr == &mut u[1] as *mut usize);
// I copied this from Stack Overflow without reading the surrounding prose
println!("{}", unsafe { *ptr });
}
fn main(){
让mut v:Vec=Vec![1,2,3];
让ptr:*mut usize=&mut v[1]作为*mut usize;
设mut u:Vec=v;
断言!(ptr==&mut u[1]为*mut usize);
//我从Stack Overflow复制了这篇文章,没有阅读周围的散文
println!(“{}”,不安全的{*ptr});
}
您应该准确记录不安全
块的安全条件以及维护安全条件的方式。在这种情况下
Vec
的元素包括:
如果Vec
已分配内存,则它指向的内存位于堆上
Vec
的任何修改导致调整大小或破坏
对于这个例子,我只使用一个索引(
1
)。对于您的树案例,我将尝试使用索引向量。基准测试以查看是否存在明显的差异。除非移动的向量的大小超出其容量(通过添加元素),否则在这种情况下,您会留下一个悬空指针(因为所有数据都复制到另一个容量更大的位置)Vec
是否真的保证在任何情况下都能将其元素保留在堆上?它是否有可能被允许进行一些小的向量优化(例如,如果一个数组中只有4个元素,则保留元素)?@AlexLarionov我可以保证移动的向量的大小不会超过其容量。@Phimueme好的,Vec
具有从原始部分和到原始部分,我认为如果存在小向量优化,它们是不可实现的。@PhimueMe Vec永远不会执行“小优化”,其中元素实际存储在堆栈()上,而在不安全块中,Vec
本身和&mut usize
将共存,编译器不会知道&mut usize
来自Vec
。一般来说,对u
的mut引用与对u[1]
的mut引用共存(只要我没有第二个对u[1]
的引用)可以接受吗?u
中没有任何引用,只有更多的原始指针。对u
的可变引用是可疑的。您将能够获得该元素的第二个可变引用;对不起,我想我不清楚。我的意思是类似于。是的,在安全的情况下不可能做这样的事。但是,如果我想通过一个期望引用的API(根据链接的代码)来改变指针中的元素,会不会因为mut ref与u
共存而立即变成UB?我可以通过执行&mutu[1]
来获取另一个mut ref,我认为这将是立即的;但是如果我没有这样做,代码会保持良好的定义吗?正如我提到的,u
中没有任何引用。因为它没有引用,所以不能与另一个引用混淆。