内存安全
内存安全性 Bug 包括二次释放。
构造和析构¶
内存管理¶
管理运行时使用计算机内存的方式: - 自动垃圾回收 - 手动分配和释放内存 - 所有权规则检查
内存管理接口¶
在 C 语言中,有 malloc()
和 free()
,可手动分配和释放内存。
内存生命周期¶
不管什么程序语言,内存生命周期基本是一致的:
- 分配你所需要的内存
- 使用分配到的内存(读、写)
- 不需要时将其释放/归还
所有语言第二部分都是明确的。第一和第三部分在底层语言中是明确的,但在高级语言中,大部分都是隐含的。
内存分配¶
静态内存分配是按计划分配,由编译器负责; 动态内存分配是按需分配,由程序员负责。
从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。
面向对象就是堆和栈的完美结合。其实,面向对象方式的程序与以前结构化的程序在执行上没有任何区别。但是,面向对象的引入,使得对待问题的思考方式发生了改变,而更接近于自然方式的思考。当我们把对象拆开,你会发现,对象的属性其实就是数据,存放在堆中;而对象的行为(方法),就是运行逻辑,放在栈中。我们在编写对象的时候,其实即编写了数据结构,也编写的处理数据的逻辑。
内存释放¶
自动垃圾回收¶
引用计数¶
标记-清除¶
所有权系统¶
基本概念¶
- 借用: 将创建一个引用的行为称为 借用
- 引用:一个地址
- 可变引用:修改一个借用的值
- 悬垂引用:指向的内存可能已经被分配给其它持有者
所有权规则¶
- Rust 中的每一个值都有一个 所有者(owner)。
- 值在任一时刻有且只有一个所有者。
- 当所有者(变量)离开作用域,这个值将被丢弃。
所有权策略¶
只在栈上的数据¶
拷贝
在堆上的数据¶
移动或克隆
作用域¶
当变量离开作用域后,Rust 自动调用 drop
函数并清理变量的堆内存。
引用的规则¶
- 在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。
- 引用必须总是有效的。
生命周期¶
生命周期确保引用有效
资源¶
最后更新: September 10, 2023