Rust 如何保证内存安全并防止段错误?

2024-02-19

我一直在寻找一种可以学习的语言,并且我发现 Rust 变得非常流行。

Rust 有两件事给我留下了深刻的印象:内存安全和防止段错误。

Rust 是如何实现这一点的呢?例如,Rust 和 Java 之间的哪些差异使得 Rust 具有安全功能?


Rust 如何实现内存安全,其核心实际上非常简单。它主要取决于两个原则:所有权和借贷。

所有权

编译器使用仿射类型系统来跟踪每个值的所有权:一个值最多只能使用一次,之后编译器拒绝再次使用它。

fn main() {
    let original = "Hello, World!".to_string();
    let other = original;
    println!("{}", original);
}

产生错误:

error[E0382]: use of moved value: `original`
 --> src/main.rs:4:20
  |
3 |     let other = original;
  |         ----- value moved here
4 |     println!("{}", original);
  |                    ^^^^^^^^ value used here after move
  |
  = note: move occurs because `original` has type `std::string::String`, which does not implement the `Copy` trait

值得注意的是,这可以防止可怕的双免在 C 或 C++ 中经常遇到(在智能指针之前)。

借款

Rust 的启示是,当混合使用别名和可变性时,就会出现内存问题:也就是说,当一块内存可以通过多个路径访问并且它被突变(或移走)时留下了悬空指针.

因此,借用检查的核心原则是:可变性 XOR 别名。原则上它类似于读写锁。

这意味着 Rust 编译器跟踪aliasing信息,它使用生命周期注释 (those 'a in &'a var) 将引用的生命周期和它们引用的值连接在一起。

如果某人引用了某个值或对其进行了 INTO(例如,对某个字段的引用),则该值被借用struct或集合的元素)。借用的值无法移动。

可变性(无别名)

您只能获得一个可变引用 (&mut T) 随时变为给定值,并且没有不可变的引用成这个值可能同时存在;它保证您可以独占访问该内存片段,因此您可以安全地对其进行变异。

别名(无可变性)

您可以获得多个不可变的引用 (&T) 随时变为给定值。但是,您不能通过这些引用 (*) 改变任何内容。

(*) 我在说谎;有像这样的结构RefCell实现“内部可变性”;他们确实尊重可变性异或别名原则,但将检查推迟到运行时。

就是这样?

几乎如此;)

对于编译器编写者来说,实现起来已经相当复杂,并且可能会过度限制用户(一些安全的程序无法使用该系统证明安全,需要跳过障碍),但核心原理确实如此简单。

那么还剩下什么呢?

边界检查。这不是火箭科学,但可能会导致性能损失。大多数语言都对其有一定程度的支持,C 是一个大例外,而 C++ 有some支持它,尽管它是可选的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rust 如何保证内存安全并防止段错误? 的相关文章

随机推荐

  • 当用户单击 Qt 应用程序中的任务栏/停靠栏图标时获取事件或通知

    我正在 osx windows linux 上开发应用程序 我想制作像 Skype 这样的功能 当用户单击关闭窗口时 应用程序不会退出而是隐藏 当用户单击扩展坞或任务栏上的应用程序图标时 我的主窗口将再次重新打开 当用户单击应用程序图标时
  • Java BufferedWriter 关闭()

    假设我有以下代码片段 operation1 bw close operation2 当我打电话时BufferedReader close 从我的代码中 我假设我的 JVM 进行了一个系统调用 以确保缓冲区已被刷新并写入磁盘 我想知道是否cl
  • 如果 Python 是解释型的,那么 .pyc 文件是什么?

    Python 是一种解释型语言 但为什么我的源目录包含 pyc文件 Windows 将其识别为 编译的 Python 文件 我已经明白了 Python 是一种解释型语言 这种流行的模因是不正确的 或者更确切地说 是建立在对 自然 语言水平的
  • Prisma - 如何将两个字段指向同一模型?

    我很难概念化如何处理这个问题 我仔细研究了 Prisma 文档和其他 SO 问题 但它们似乎都与这种情况略有不同 我有两个模型 model User id Int id default autoincrement firstName Str
  • 如何对 Jackson JsonSerializer 和 JsonDeserializer 进行单元测试

    我为我的应用程序编写了自定义 JsonSerializer 和 JsonDeserializer 现在我想为它们编写一些单元测试 一个干净的测试用例应该是什么样的 有一些干净的例子吗 干净意味着不依赖其他框架或库 Json序列化器 该示例正
  • AppendTargetFrameworkToOutputPath 在 .targets 文件中失败

    我正在尝试集中许多项目的一些构建配置 而 MSBuild 解决方案是使用 targets files https learn microsoft com en us visualstudio msbuild msbuild dot targ
  • 在 django 中通过拖放对项目进行排序

    在我的 django 项目中 我在模板中显示了书籍列表 Book型号有position我用来对书籍进行排序的字段 我试图通过拖放列表项对该列表进行排序 但我的下一个代码不能很好地工作 我用jQuery 用户界面 它在前端工作 但当用户拖放列
  • 将文本区域保存到文件

    是否可以将文本区域保存到文件中 FileWriter fw new FileWriter file1 getAbsoluteFile true BufferedWriter bw new BufferedWriter fw bw write
  • 来自一组键的 PHP 数组

    发现这篇文章对我有帮助 拆分字符串以形成多维数组键 https stackoverflow com questions 10519108 split a string to form multidimensional array keys
  • 给定一个字符串,找到元音和辅音数量相同的最长子串?

    给定一个字符串 找到元音和辅音数量相同的最长子串 澄清 我不确定我们是否可以生成一个新字符串 或者子字符串必须是原始字符串的一部分 到目前为止我有这个 代码片段 Scanner scanner new Scanner System in S
  • R 的丰富 Ctags

    是否有任何使用记录ctags http ctags sourceforge net 与 R 这有用吗 实施起来会不会很困难 具体来说 我刚刚开始使用 Vim 如果能够在一个文件中编写 R 函数 在另一个文件 例如 Rnw 文件 测试文件或其
  • 为什么 PayPal 的 IPN 模拟器不能使用 https 地址?

    在 PayPal 的 IPN 模拟器中 如果我输入 https URL 则会收到一条错误消息 很抱歉 我们无法发送 IPN 但是 在 http URL 上它工作正常 我该如何解决这个错误 这可能是因为您的 SSL 证书是自签名的或被 Pay
  • Java Calendar.DAY_OF_WEEK 给出了错误的日期

    下面的代码有什么问题 对于一年中的任何日期 它给出的日期都是错误的 import java util Scanner import java util Calendar public class Solution public static
  • 请求在 chrome 中偶尔会停滞很长时间

    Ajax 请求有时会在 Chrome 中长时间停滞 我终于成功地复制了它并保存了所有必要的相关数据 如果有人可以帮助我的话 可以在这里发布 The timeline from Chrome Dev Tool shows the reques
  • JavaScript ArrayBuffer 切片在 Safari 9.1.2 中明显损坏

    Safari 9 1 2 10601 7 7 中的基本 JavaScript 功能似乎被破坏 也许我只是做错了什么 正在寻求有关如何度过这一切的建议 有问题的函数是ArrayBuffer prototype slice https deve
  • llvm/clang 编译错误,内存耗尽

    我正在尝试在我的 ubuntu 14 04 虚拟机 具有 2GB 内存 上构建最新的 llvm clang 代码 我所做的是正常的配置 制作过程 这两个命令没有任何参数 最后 我有以下错误 llvm 4 链接 Debug Asserts 可
  • 如何使用 laravel 5.1 使用更新记录的 user_id 填充 modded_by ?

    使用 Laravel 5 1 时 我尝试创建一个观察者 它将自动更新以下 3 列 created by 当创建的记录 不再更新 时填充 Modified by 每次修改记录时填充新值 purged by 软删除记录时填充一个值 我知道 El
  • 尽管有 SecurityConfig,Spring Security 仍会阻止 POST 请求

    我正在开发一个基于 Spring Boot 的 REST API spring boot starter web 我使用Spring Security spring security core e spring security confi
  • 调试 MFC:“mfc100.dll”找不到或打开 pdb

    我正在尝试在调试时进入 MFC 源代码 但是 Visual Studio 显然在加载适当的符号时遇到问题 C WINDOWS symbols dll mfc100 i386 pdb PDB 与图像不匹配 我检查了其他问题 通常建议启用 符号
  • Rust 如何保证内存安全并防止段错误?

    我一直在寻找一种可以学习的语言 并且我发现 Rust 变得非常流行 Rust 有两件事给我留下了深刻的印象 内存安全和防止段错误 Rust 是如何实现这一点的呢 例如 Rust 和 Java 之间的哪些差异使得 Rust 具有安全功能 Ru