Rust程式設計中的不安全操作


當我們想要忽略Rust提供的規範時,就會執行不安全操作。我們可以使用不同的不安全操作,主要包括

  • 解引用原始指標
  • 訪問或修改靜態可變變數
  • 呼叫宣告為unsafe的函式或方法

儘管Rust不建議我們使用不安全操作,但我們應該只在想要繞過編譯器提供的保護措施時才使用它們。

原始指標

 在Rust中,原始指標 * 和引用 &T 執行幾乎相同的功能,但引用始終是安全的,因為編譯器保證它們指向有效的資料,這得益於借用檢查器。

還應該注意,解引用原始指標只能在unsafe塊中完成。

示例

考慮以下示例

fn main() {
   let raw_p: *const u32 = &10;
   println!("{}",*raw_p == 10);
}

以上程式碼將導致錯誤。

輸出

error[E0133]: dereference of raw pointer is unsafe and requires
unsafe function or block
 --> src/main.rs:4:19
  |
7 | println!("{}",*raw_p == 10);
  | ^^^^^^ dereference of raw pointer
  |
  = note: raw pointers may be NULL, dangling or unaligned; they
can violate aliasing rules and cause data races: all of these are
undefined behavior

為了避免此錯誤,我們需要使用unsafe塊,然後才能解引用原始指標。

示例

考慮以下程式碼:

線上演示

fn main() {
   let raw_p: *const u32 = &10;
   unsafe {
      assert!(*raw_p == 10);
   }
   println!("worked fine!")
}

輸出

worked fine!

不安全函式

在Rust中呼叫不安全函式將導致錯誤。

示例

考慮以下程式碼

use std::slice;

fn main() {
   let some_vector = vec![1, 2, 3];

   let pointer = some_vector.as_ptr();
   let length = some_vector.len();
   let my_slice: &[u32] = slice::from_raw_parts(pointer, length);
   assert_eq!(some_vector.as_slice(), my_slice);
}

輸出

在以上程式碼中,我們有一個slice::from_raw_parts函式,它是unsafe的,如果我們嘗試執行此程式碼,我們將看到類似這樣的錯誤 -

error[E0133]: call to unsafe function is unsafe and requires
unsafe function or block
--> src/main.rs:10:28
   |
10 | let my_slice: &[u32] = slice::from_raw_parts(pointer,
length);
   |
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
   |
   = note: consult the function's documentation for information on
how to avoid undefined behavior

我們不應該在任何地方呼叫此函式,而應該在unsafe塊內呼叫不安全函式。

示例

考慮以下程式碼

線上演示

use std::slice;

fn main() {
   let some_vector = vec![1, 2, 3, 4];

   let pointer = some_vector.as_ptr();
   let length = some_vector.len();

   unsafe {
      let my_slice: &[u32] = slice::from_raw_parts(pointer, length);
      assert_eq!(some_vector.as_slice(), my_slice);
   }
   println!("worked fine!!")
}

輸出

worked fine!!

更新於: 2021年4月5日

179次瀏覽

開啟您的職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.