之前文章介紹rust的記憶體模型和所有權機制,保障了rust中記憶體的安全。但有些時候,編譯器無法幫我們確定一個指標是否合法(為空或者懸空指標),這就需要開發者告訴編譯器,這個記憶體的使用是否安全,rust 透過關機中unsafe標識。
比如下面的程式碼
fn main() { let mut value = 10; //透過as 轉化為裸指標 let immutable_raw_pointer = &value as *const i32; let mutable_raw_pointer = &mut value as *mut i32; // 列印指標 print!("value is: {}", *immutable_raw_pointer); print!("value is: {}", *mutable_raw_pointer);}
編譯執行的時候則會提示,提示不安全的記憶體使用
此時需要我們手動標註這段記憶體的操作是非安全的,程式碼就可以順利運行了,如下:
fn main() { let mut value = 10; let immutable_raw_pointer = &value as *const i32; let mutable_raw_pointer = &mut value as *mut i32; unsafe { print!("value is: {}", *immutable_raw_pointer); print!("value is: {}", *mutable_raw_pointer); }}
這個unsafe 等於告訴編譯器,開發者自己知道這裡存在記憶體不安全情況,但我仍然需要這樣使用,開發者自己保證記憶體安全。
String 裡面的from_raw_parts 就是一個unsafe 的方法
pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String {
因為它需要將一個u8的序列轉化為utf-8 的字串,但這個u8 序列很可能並不是utf-8 編碼的,所以需要使用unsafe 標識,這樣開發者在呼叫這個方法的時候,就需要在外部新增一個unsafe,從而提示開發者在使用這個方法的時候,需要保障傳入合法的utf-8 字元序列。
fn main() { let s = String::from("hello"); let mut s = mem::ManuallyDrop::new(s); let ptr = s.as_mut_ptr(); let len = s.len(); let capacity = s.capacity(); unsafe { let s = String::from_raw_parts(ptr, len, capacity); }}
最新評論