Rust memory management: Difference between revisions

From wikinotes
Line 47: Line 47:
     print_str(s);      // `s` does not have `Copy` trait, pointer passed to function, which now owns it
     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
     println!("{}", s);  // <-- BANG! not allowed to use `s` anymore
}
</syntaxhighlight>
Passing references enables passing objects to arguments without transferring ownership
<syntaxhighlight lang="rust">
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
}
}
</syntaxhighlight>
</syntaxhighlight>
</blockquote><!-- Ownership -->
</blockquote><!-- Ownership -->
</blockquote><!-- General -->
</blockquote><!-- General -->

Revision as of 17:19, 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

  • 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
}

Passing references enables passing objects to arguments without transferring ownership

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
}