對裸指標解參考
建立指標相當安全,不過對指標解參考就需要使用 unsafe
:
fn main() { let mut s = String::from("careful!"); let r1 = &mut s as *mut String; let r2 = r1 as *const String; // Safe because r1 and r2 were obtained from references and so are // guaranteed to be non-null and properly aligned, the objects underlying // the references from which they were obtained are live throughout the // whole unsafe block, and they are not accessed either through the // references or concurrently through any other pointers. unsafe { println!("r1 is: {}", *r1); *r1 = String::from("uhoh"); println!("r2 is: {}", *r2); } // NOT SAFE. DO NOT DO THIS. /* let r3: &String = unsafe { &*r1 }; drop(s); println!("r3 is: {}", *r3); */ }
This slide should take about 10 minutes.
It is good practice (and required by the Android Rust style guide) to write a comment for each unsafe
block explaining how the code inside it satisfies the safety requirements of the unsafe operations it is doing.
In the case of pointer dereferences, this means that the pointers must be valid, i.e.:
- The pointer must be non-null.
- The pointer must be dereferenceable (within the bounds of a single allocated object).
- The object must not have been deallocated.
- There must not be concurrent accesses to the same location.
- If the pointer was obtained by casting a reference, the underlying object must be live and no reference may be used to access the memory.
In most cases the pointer must also be properly aligned.
「NOT SAFE」部分提供了常見的 UB 錯誤示例:*r1
具有 'static
生命週期,因此 r3
具有 &'static String
這個型別,從而會超過 s
。從指標建立參照需要「格外謹慎」__。