Rust原始指针内存分配:基地址、值及指针自身地址疑问
Rust原始指针内存分配相关疑问解答
先看你的代码和测试结果:
pub struct Allocator { heap_start: NonNull<u8>, size: usize } impl Allocator { unsafe fn init(size: usize) -> Result<Allocator, LayoutError>{ let layout = std::alloc::Layout::from_size_align(size, size)?; let heap = NonNull::new(std::alloc::alloc(layout)).unwrap(); Ok(Allocator { heap_start: heap, size, }) } } #[test] fn test_alloc_init() { match unsafe { Allocator::init(64) } { Ok(alloc) => unsafe { let val = alloc.heap_start; println!("the address is {:?} and value is {:?}", val.as_ptr(), *val.as_ptr()); }, Err(erro) => { assert!(false) } } }
测试输出:the address is 0x7f8e5b804080 and value is 0
疑问1:为何基地址对应的值为0?该地址未存储任何内容?
std::alloc::alloc分配的内存本身是未初始化的,但实际运行时,操作系统或内存分配器可能返回已清零的内存块——比如空闲内存页本来就是零填充的,或者分配器会主动清零回收后的内存。你看到的0是巧合,不是必然结果,未初始化内存的值属于未定义行为,不能依赖它的具体值。
疑问2:获取的基地址是否正确,是否存在操作错误?
基地址是正确的。NonNull::new(std::alloc::alloc(layout)).unwrap()已经确保内存分配成功,val.as_ptr()返回的就是分配到的内存块的起始原始指针。
不过代码有个潜在问题:Layout::from_size_align(size, size)用size作为对齐要求,当size不是2的幂时会返回LayoutError(比如传入奇数),这通常不是合理的对齐策略——一般内存分配的对齐要求应该用目标类型的对齐值,或者默认对齐(比如u8的对齐是1),而非和内存大小绑定。
疑问3:如何获取指针自身的地址?
你尝试的&*val.as_ptr()是错误的,这是对原始指针解引用后取地址,结果还是内存块的起始地址,不是指针变量自身的地址。
要获取指针变量自身的地址,需要对变量本身取引用:
- 若要获取
NonNull<u8>类型变量val的地址:直接用&val,它的类型是&NonNull<u8>,可转为原始指针&val as *const NonNull<u8>。 - 若要获取
val.as_ptr()得到的*const u8这个原始指针值的存储地址,需先将原始指针存入变量再取地址:
这里let raw_ptr = val.as_ptr(); let ptr_self_addr = &raw_ptr as *const *const u8; println!("指针自身的地址:{:?}", ptr_self_addr);ptr_self_addr就是存储raw_ptr这个变量的内存地址,也就是你要的指针自身的地址。
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

