面试题答案
一键面试- 安全问题:
- 空指针解引用:解引用空指针会导致未定义行为。例如,如果有一个
*const i32
类型的指针,它可能为空,如果直接解引用它,就会出现未定义行为。 - 悬垂指针解引用:当指针所指向的内存已经被释放,再去解引用该指针,也会导致未定义行为。比如一块内存被分配给一个指针,然后这块内存被释放了,指针却没有更新,之后再解引用该指针。
- 未初始化内存访问:如果指针指向的是未初始化的内存,解引用该指针也会导致未定义行为。
- 空指针解引用:解引用空指针会导致未定义行为。例如,如果有一个
- 避免方法及示例:
- 检查空指针:
fn main() {
let ptr: *const i32 = std::ptr::null();
if!ptr.is_null() {
let value = unsafe { *ptr };
println!("Value: {}", value);
}
}
- 确保内存有效:使用
Box
或其他内存管理类型来确保内存有效,避免悬垂指针。例如:
fn main() {
let boxed = Box::new(42);
let ptr: *mut i32 = boxed.as_mut();
let value = unsafe { *ptr };
println!("Value: {}", value);
// 当`boxed`离开作用域时,内存会被正确释放,并且不会导致悬垂指针
}
- 初始化内存:在使用指针前确保内存已初始化。比如使用
std::mem::uninitialized
创建未初始化内存后,要先初始化再解引用:
use std::mem;
fn main() {
let mut uninit: mem::MaybeUninit<i32> = mem::MaybeUninit::uninit();
unsafe {
uninit.as_mut_ptr().write(42);
let value = uninit.assume_init();
println!("Value: {}", value);
}
}
总之,在Rust中解引用原始指针时,必须在unsafe
块中进行,并要特别注意空指针、悬垂指针以及内存初始化等安全问题。