82 lines
3.9 KiB
Rust
82 lines
3.9 KiB
Rust
/* 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 <moved> // not can be used,
|
||
|
||
stack-slots2 stack-slots1
|
||
owner2 (on stack) owner1 (on stack)
|
||
+-------------------+ +-----------------------+
|
||
| ptr → heap "hello"| | <ptr moved / invalid> |
|
||
| len = 5 | + <len moved / invalid> +
|
||
| cap = 5 | | <cap moved / invalid> |
|
||
+-------------------+ +-----------------------+
|
||
|
||
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.
|