目前为止,这机制工作的不错.但是不是所有的事情都是这样的.有时,你需要在不同的函数中传递内存数据,或者你需要把内存数据的生命期拉长到一个函数范围之外.为此,我们可以用堆.
在Rust语言中,你可以试用Box<T>类型来分配堆上的内存空间.这有个例子:
fn main() {
let x = Box::new(5);
let y = 42;
}
当main()函数调用的时候,内存是这样的:
我们在栈上分配了2个变量.y是42,正如以往的一样,那么x又是什么呢?x是一个Box<i32>,boxes是在堆上分配的内存.x的真正值是一个数据结构,它包含了一个指针,指向了堆.当我们开始执行这个函数的时候,Box::new()会被调用,这会在堆上分配一些空间,然后把5这个数放进去.内存现在看起来像这样:
地址 |
名字 |
值 |
230 |
|
5 |
... |
... |
... |
1 |
y |
42 |
0 |
x |
230 |
Page 68
在1GB的内存中,我们假设堆的起始地址是230.因为栈地址是从0开始增加的,最简单的方法就是从另外一端开始分配.所以我们的第一个值就在内存的最高地址.另外,在x处的结构体是一个裸指针,它指向了我们分配的堆的地址,所以x的值就是230,我们分配这个地址的时候得到的值.
我们还没有真正讨论过分配和释放内存到底意味着什么.深入探讨这些内容超出了本书的范围,但是目前我们需要知道的重要的地方就是堆和栈具有相反的增长方向.本书的后面我们会有例子,因为我们可以任意的以任意的顺序分配和释放内存,这样就会在内存中形成一些"洞".这里有一个图显示出当程序运行了一段时间后的状态:
地址 |
名字 |
值 |
230 |
|
5 |
(230)-1 |
|
|
(230)-2 |
|
|
(230)-3 |
|
42 |
... |
... |
... |
3 |
y |
(230)-3 |
2 |
y |
42 |
1 |
y |
42 |
0 |
x |
230 |
在此例中,我们在堆上分配了4个变量,但是只释放了2个.在230和(230)-3之间有一段空隙,没有被使用.具体的细节取决于你管理内存的策略.不同的程序会使用不同的内存管理策略,通过一些库函数.Rust程序使用jemalloc来完成内存管理.
回到我们的程序来.因为这段空间分配在栈上,它可以比分配box的函数生存的更久.在此例,它并没有(生存更久).当函数结束的时候,我们会释放main()的栈帧.而Box<T>类型还有一个"小把戏":Drop.Box类型的Drop操作可以实现释放内存的功能.很好!所以当x离开作用域的时候,他释放了堆上的内存:
Page 69
然后栈帧也释放,内存也释放了.
4.1.4 参数和借用(borroing)
我们已经有了一些基本的关于栈和堆的例子,但是参数和借用呢?这有一个Rustxiaochengxu :
fn foo(i:&i32) {
let z = 42;
}
fn main() {
let x = 5;
let y = &x;
foo(y);
}
当我们进入main()函数是,内存是这样的:
x的值是基本数值5,y是x的一个引用.所以y的值就是x的内存地址,也就是0.
那么当我们调用foo()函数,并传入y参数呢?
地址 |
名字 |
值 |
3 |
z |
42 |
2 |
i |
0 |
1 |
y |
0 |
0 |
x |
5 |
栈帧并不仅仅针对局部变量,参数也是的.所以在此例中,我们同时需要参数i和z变量绑定.i就是参数y的一个拷贝.因为y的值是0,所以i也是0.
Page 70
借用并不会释放内存,原因是这样的:一个引用的值仅仅是一个指向内存地址的指针.如果我们不使用相应的内存,就无法正常工作.
4.1.5 一个复杂的例子
OK.让我们一步一的分析一个复杂的例子:
fn foo(x: &i32) {
let y = 10;
let z = &y;
baz(z);
bar(x, z);
}
fn bar(a: &i32, b: &i32) {
let c = 5;
let d = Box::new(5);
let e = &d;
baz(e);
}
fn baz(f: &i32) {
let h = 3;
let i = Box::new(20);
let j = &h;
foo(j);
}
首先,我们调用main()函数:
地址 |
名字 |
值 |
230 |
|
20 |
... |
... |
... |
2 |
j |
0 |
1 |
i |
230 |
0 |
h |
3 |
分享到:
相关推荐
rust自动翻译中文rust自动翻译中文,除
欢迎阅读!这本书将教会你使用Rust编程语言。
Rust 核心库和标准库中文翻译 Rust 核心库和标准库中文翻译 Rust 核心库和标准库中文翻译 Rust 核心库和标准库中文翻译 Rust 核心库和标准库中文翻译 ...
官网最新翻译。
Rust 代码和资源的精选列表中文翻译
官网最新翻译。
中文版(Rust by Example)Rust社区官方翻译,翻译精准可靠,非常适合Rust入门学习,主要讲述Rust基本语法
Rust Reference 的中文翻译,预期能及时和原文保持同步rust-reference-master.zip
Steve Klabnik 和 Carol Nichols,以及来自 Rust 社区的贡献(Rust 中文社区翻译) 本书假设你使用 Rust 1.37.0 或更新的版本,且在所有的项目中的 Cargo.toml 文件中通过 edition="2018" 采用 Rust 2018 Edition ...
Rust 核心库和标准库中文翻译,可作为 IDE 工具的智能提示,并生成本地 API 文档
Rust 程序设计语言 简体中文版 ---------------------------------------------------- 本 ePub 基于开源文档,目录书签齐全。 版权归原作者,翻译版权归译者。 --------------------------------------------------...
官网最新翻译。
中文翻译:<rust-lang/rustlings> 帮你扶住 Rust 的那双手 ❤️ ✅
Rustc Dev Guide 中文翻译 的中文翻译已经启动。因为原项目还在变动期,为了翻译方便,所以此翻译项目组织结构就不和原项目保持一致了。志愿者招募要求:热爱 Rust,对 Rust 已经有一定了解想深入了解 Rust 编译器想...
本文档为 The Rust Programming Language 的中文翻译。
Rust编程语言 rust-book 中文翻译 (进行中...) 本项目是对的中文翻译, 力求语言准确,正确还原原文内容,规避任何看起来像机器翻译的句子。 完整书籍: github: 勘误:
:globe_with_meridians: 这是《 The Rust Programming Language》一书的法文翻译 翻译在文件夹中。 其他所有内容都应保留在英语书中(某些必需的文件除外,例如README.md) 。 想要帮助翻译吗? 请阅读文件 ! ...
注1:《Rust Cookbook 中文版》翻译自 rust-lang-nursery 团队撰写的 "A Rust Cookbook",感谢 rust-lang-nursery 团队的无私奉献!注2:《Rust Cookbook 中文版》计划为两个阶段:第一阶段:经仔细斟酌,形成专业、...
目前翻译到第十六章, 还在翻译中。。。。。。。。。。
Rust 核心库和标准库中文翻译,可作为 IDE 工具的智能提示,并生成本地 API 文档