/* Rust Concepts: https://sociocyber.site/rust_concepts_v2.html Concept: Ownership One value = One owner owner means -> who have something Ownership means moves ptr1's address into ptr2 (this happens in stack) Moving structs from [stack-slots1] into [stack-slots2] ptr - pointer (similar to pointer in C/C++) Variable(owner) saved in scope, when runtime out of scope, then the value is freed automaticly from MEM. (no garbage collector) In rust garbage collector is not used. Borrwing & prevent ┌─────────────────────┐ ┌─────────────────────┐ │ Stack – owner1 │ │ Stack – owner2 │ │ (before move) │ │ (after move) │ │ │ │ │ │ +----------------+ │ │ +----------------+ │ │ | ptr → heap "V" | │ move → │ | ptr → heap "V" | │ │ | len = 5 | │ │ | len = 5 | │ │ | cap = 5 | │ │ | cap = 5 | │ │ +----------------+ │ │ +----------------+ │ └─────────────────────┘ └─────────────────────┘ Heap (single allocation) ┌───────────────────────────────────────┐ │ 0xABCDEF00: V a l u e … │ └───────────────────────────────────────┘ Scope ends → drop(owner2) → memory freed Heap (single allocation - out of scope) ┌───────────────────────────────────────┐ │ 0xABCDEF00: … │ └───────────────────────────────────────┘ */ fn main() { let owner1 = String::from("Value"); // ? save "Value" in heap, stack (owner1) → ptr → heap "hello" /* stack-slots1 +-------------------+ ← lower address (stack grows down) | ptr → heap "hello"| ← 8 bytes | len = 5 | ← 8 bytes | cap = 5 | ← 8 bytes +-------------------+ ← higher address heap address (ptr) → [ 'h' 'e' 'l' 'l' 'o' ] */ let owner2 = owner1; // owershipped! owner1 moves (ship) his value into owner1. stack (owner2) → ptr (getted from owner1) → heap "hello" /* stack slot (owner2) ──► ptr → heap "hello" stack slot (owner1) ──► ptr // not can be used, stack-slots2 stack-slots1 owner2 (on stack) owner1 (on stack) +-------------------+ +-----------------------+ | ptr → heap "hello"| | | | len = 5 | + + | cap = 5 | | | +-------------------+ +-----------------------+ heap address (ptr) → None (not valid) */ // println!("{}", owner1); // owner1 no longer valid, not ptr. (Compiler thinks this about as 'None') // Not actual address for heap, where value println!("(Ownership) owner1 -> owner2; owner2 = {}", owner2); } // owner2 Out of the scope, drops owner2 for free a heap // When owner2 and owner1 go out of scope, they will both try to free the same memory. This is known as a double free error and is one of the memory safety bugs we mentioned previously. Freeing memory twice can lead to memory corruption, which can potentially lead to security vulnerabilities. // To ensure memory safety, after the line let owner2 = owner1;, Rust considers owner1 as no longer valid. // Therefore, Rust doesn’t need to free anything when owner1 goes out of scope.