Rust memory management: Difference between revisions
From wikinotes
Line 28: | Line 28: | ||
== Ownership == | == Ownership == | ||
<blockquote> | |||
=== Copy Trait === | |||
<blockquote> | <blockquote> | ||
* Objects have a single owner at once | * Objects have a single owner at once | ||
Line 49: | Line 51: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</blockquote><!-- Copy Trait --> | |||
=== References === | |||
<blockquote> | |||
Passing references enables passing objects to arguments without transferring ownership.<br> | Passing references enables passing objects to arguments without transferring ownership.<br> | ||
However: | However: | ||
Line 65: | Line 70: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
In rust, because of lifetime semantics, you can't return a reference from an object created in a function.<br> | |||
You need to return the object itself, so that it's ownership is transferred. | |||
<syntaxhighlight lang="rust"> | |||
// INVALID! | |||
fn foo() -> &String { | |||
let s = String::from("hi"); | |||
&s | |||
} | |||
// VALID | |||
fn foo() -> String { | |||
let s = String::from("hi"); | |||
s | |||
} | |||
</syntaxhighlight> | |||
</blockquote><!-- References --> | |||
</blockquote><!-- Ownership --> | </blockquote><!-- Ownership --> | ||
</blockquote><!-- General --> | </blockquote><!-- General --> |
Revision as of 17:33, 7 February 2023
Rust uses ownership semantics for memory management.
Documentation
official tutorial https://doc.rust-lang.org/stable/book/ch04-00-understanding-ownership.html
General
Stack
The stack is
- a LIFO
- push=add, pop=remove (from the top)
- only supports fixed-size datatypes
- fast
Heap
- access provided through pointers (a fixed-size, usable on stack)
- slower
Ownership
Copy Trait
- Objects have a single owner at once
- When owner goes out of scope, value is dropped (with
drop()
)- When an object is passed as a function-parameter, that function now owns it (and it cannot be referenced in current context).
See example of ownership in action.
fn print_i32(i: i32) { println!("{}", i); } fn print_str(s: String) { println!("{}", s); } fn main() { let i = 123; print_i32(i); // `i` has `Copy` trait, `foo` gets a shallow copy println!("{}", i); // valid! `i` is still owned by `main()` let s = String::from("abc"); print_str(s); // `s` does not have `Copy` trait, pointer passed to function, which now owns it println!("{}", s); // <-- BANG! not allowed to use `s` anymore }References
Passing references enables passing objects to arguments without transferring ownership.
However:
- only a single mutable reference can exist for the same object at a time.
- if a mutable reference for an object exists, there cannot be immutable references to that object
I'm thinking of this as a read/write lock (multiple readers allowed, nobody can read/write while writing).
fn print_str(s: &String) { println!("{}", s); } fn main() { let s = String::from("abc"); print_str(&s); println!("{}", s); // <<-- valid! `main` still owns the object }In rust, because of lifetime semantics, you can't return a reference from an object created in a function.
You need to return the object itself, so that it's ownership is transferred.// INVALID! fn foo() -> &String { let s = String::from("hi"); &s } // VALID fn foo() -> String { let s = String::from("hi"); s }