将指针存储为另一个指针的值的最佳方法是什么?
我有一个ptr
类型的变量*mut u8
。如何将ptr
指向的地址存储为同样为[{1}}类型的另一个指针t
的值。
我正在尝试做类似
的事情*mut u8
我收到*t = ptr;
错误。我知道地址expected u8, found *-ptr
将是64位。我想从地址ptr
开始填充64位。
答案 0 :(得分:6)
我有一个
ptr
类型的变量*mut u8
。如何将ptr
指向的地址存储为另一个指针t
的值*mut u8
将一个指针指向另一个:
use std::ptr;
fn main() {
let ptr: *mut u8 = ptr::null_mut();
let t: *mut u8 = ptr;
}
ptr
是一个指针,它指向的地址是NULL
。此值现在存储在与t
相同类型的指针ptr
中:t
指向地址NULL
。
+-----+ +-----+
| | | |
| ptr | | t |
| | | |
+--+--+ +--+--+
| |
| |
+---->NULL<----+
如果您希望t
成为指向另一个指针的地址的指针,则需要引用ptr
。类型也可能不一样:
use std::ptr;
fn main() {
let ptr: *mut u8 = ptr::null_mut();
let t: *const *mut u8 = &ptr;
}
+-----+ +-----+
| | | |
| t +------> ptr +----->NULL
| | | |
+-----+ +-----+
我正在寻找一种方法来将
,我也可以获取地址ptr
指向的地址写入特定位置,这样即使我没有t
原始指针没有与它们相关联的编译器强制生命周期。如果你想在值消失后保留某些东西的地址,这对他们来说是理想的情况 - 你不需要做任何事情:
use std::ptr;
fn do_not_dereference_this_result() -> *const u8 {
let val: u8 = 127;
let ptr: *const u8 = &val;
ptr
}
fn main() {
println!("{:p}", do_not_dereference_this_result())
}
在极少数情况下,您可能希望将地址存储在usize
(指针大小的整数值)中:
use std::ptr;
fn do_not_dereference_this_result() -> usize {
let val: u8 = 127;
let ptr: *const u8 = &val;
ptr as usize
}
fn main() {
println!("{:x}", do_not_dereference_this_result())
}
它真的听起来像你对指针的工作方式感到困惑,这是一个很好的迹象,如果你使用它们,你将会自己开枪。我强烈鼓励您在任何重要代码中单独使用引用,直到您对指针的理解增加为止。
答案 1 :(得分:-1)
你通常不想这样做,但我相信你知道你在做什么。
这里的关键是了解一些事情:
Box<T>
大致相当于在堆上分配的*T
,您可以使用Box::into_raw
将其转换为*T
。
如果你这样做,你就会有效地泄漏分配了Box<T>
的堆,因为Rust不再知道它在哪里,或者跟踪它。您必须在某个时刻手动将其转换回可放置的对象,例如使用Box::from_raw
。
你必须 Box::new(...)
一个值,以确保它被放在堆上,否则你的原始指针将指向堆栈,最终将变为无效。
可变别名(意味着指向同一数据的两个&mut T
)会导致未定义的行为。非常重要的是要理解未定义的行为不是由并发写入触发到可变别名......它由mutable aliases existing at the same time, in any scope触发。
...但是,如果你真的想,你会这样做:
let foo_ref = Box::into_raw(Box::new(10));
let foo_ref_ref = Box::into_raw(Box::new(foo_ref));
// Modify via raw pointer
unsafe {
**(foo_ref_ref as *const *mut i32) = 100;
}
// Read via raw pointer
unsafe {
println!("{:?}", **foo_ref_ref);
}
// Resolve leaked memory
unsafe {
Box::from_raw(foo_ref_ref);
Box::from_raw(foo_ref);
}