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次浏览

开启您的职业生涯

通过完成课程获得认证

开始学习
广告