]> git.lizzy.rs Git - rust.git/blob - src/doc/tarpl/ownership.md
frob emphasis
[rust.git] / src / doc / tarpl / ownership.md
1 % Ownership and Lifetimes
2
3 Ownership is the breakout feature of Rust. It allows Rust to be completely
4 memory-safe and efficient, while avoiding garbage collection. Before getting
5 into the ownership system in detail, we will consider the motivation of this
6 design.
7
8 We will assume that you accept that garbage collection (GC) is not always an
9 optimal solution, and that it is desirable to manually manage memory in some
10 contexts. If you do not accept this, might I interest you in a different
11 language?
12
13 Regardless of your feelings on GC, it is pretty clearly a *massive* boon to
14 making code safe. You never have to worry about things going away *too soon*
15 (although whether you still wanted to be pointing at that thing is a different
16 issue...). This is a pervasive problem that C and C++ programs need to deal
17 with. Consider this simple mistake that all of us who have used a non-GC'd
18 language have made at one point:
19
20 ```rust,ignore
21 fn as_str(data: &u32) -> &str {
22     // compute the string
23     let s = format!("{}", data);
24
25     // OH NO! We returned a reference to something that
26     // exists only in this function!
27     // Dangling pointer! Use after free! Alas!
28     // (this does not compile in Rust)
29     &s
30 }
31 ```
32
33 This is exactly what Rust's ownership system was built to solve.
34 Rust knows the scope in which the `&s` lives, and as such can prevent it from
35 escaping. However this is a simple case that even a C compiler could plausibly
36 catch. Things get more complicated as code gets bigger and pointers get fed through
37 various functions. Eventually, a C compiler will fall down and won't be able to
38 perform sufficient escape analysis to prove your code unsound. It will consequently
39 be forced to accept your program on the assumption that it is correct.
40
41 This will never happen to Rust. It's up to the programmer to prove to the
42 compiler that everything is sound.
43
44 Of course, Rust's story around ownership is much more complicated than just
45 verifying that references don't escape the scope of their referent. That's
46 because ensuring pointers are always valid is much more complicated than this.
47 For instance in this code,
48
49 ```rust,ignore
50 let mut data = vec![1, 2, 3];
51 // get an internal reference
52 let x = &data[0];
53
54 // OH NO! `push` causes the backing storage of `data` to be reallocated.
55 // Dangling pointer! User after free! Alas!
56 // (this does not compile in Rust)
57 data.push(4);
58
59 println!("{}", x);
60 ```
61
62 naive scope analysis would be insufficient to prevent this bug, because `data`
63 does in fact live as long as we needed. However it was *changed* while we had
64 a reference into it. This is why Rust requires any references to freeze the
65 referent and its owners.
66
67