我该如何决定何时使用原始指针更合适?

问题描述 投票:6回答:1

我得到的印象是,Rust旨在用于高度安全的系统。然后我注意到原始指针允许任意指针算术,它们可能导致内存安全和安全问题。

pointers rust raw-pointer
1个回答
7
投票

基本上,指针是引用另一个对象的对象。在大多数编程语言中(我猜)指针实际上只是一个指向内存地址的数字。 Rust的原始指针实际上只是 - 内存地址。 Rust中还有其他指针类型(&引用,BoxRcArc),编译器可以验证内存是否有效并包含程序认为它包含的内容。原始指针不是这种情况;无论内容如何,​​它们原则上都可以指向任何内存位置。有关详细信息,请参阅The Book

原始指针只能在unsafe块中取消引用。这些块是程序员告诉编译器的一种方式“我比你更了解这是安全的,我保证不会做任何愚蠢的事情”。

如果可能的话,通常最好避免使用原始指针,因为编译器无法推断其有效性,这使得它们通常不安全。使原始指针不安全的事情是......

  • 访问NULL指针,
  • 访问悬空(释放或无效)指针,
  • 多次释放指针,

所有这些点归结为取消引用指针。也就是说,要使用指向的内存。

但是,使用原始指针而不解除引用它们是非常安全的。这有一个用例,用于查明两个引用是否指向同一个对象:

fn is_same(a: &i32, b: &i32) -> bool {
    a as *const _ == b as *const _
}

另一个用例是外部函数接口(FFI)。如果您将一个以原始指针作为参数的C函数包装起来,则无法将它们提供给该函数。这实际上是不安全的(就像整个FFI业务一样),因为该函数可能会取消引用指针。这意味着您有责任确保指针有效,保持有效,并且不会多次释放。

最后,原始指针用于优化。例如,slice iterator使用原始指针作为内部状态。这比索引更快,因为它们避免了迭代期间的范围检查。但是,就编译器而言,它也是不安全的。库作者需要特别注意,因此使用原始指针进行优化总是存在引入通常没有生锈的内存错误的风险。

总之,原始指针的三个主要用途是:

  • “只是数字” - 你永远不会访问他们指向的记忆。
  • FFI - 你把它们传给Rust外面。
  • 内存映射I / O - 触发在固定地址访问硬件寄存器所需的I / O操作。
  • 性能 - 它们可以比其他选项更快,但编译器不会强制执行安全性。

至于何时应该使用原始指针,前三点是直截了当的:你会知道它们何时适用,因为你必须这样做。最后一点更微妙。与所有优化一样,只有在利益超过使用它们的努力和风险时才使用它们。

不使用原始指针的反例是每当其他指针类型(&引用,BoxRcArc)完成工作时。

© www.soinside.com 2019 - 2024. All rights reserved.