Ownership(avoid crash in Rust)

- Defines how memory is managed safely(without need of garbage collector) by Rust program.
- Every Variable/data have single owner at a time. When the owner goes out of scope, Rust automatically deallocates the memory.
- Ownership rules are checked at compile time.
- Ownership applies to memory allocated on heap(dynamically), Eg: String(), vector ie those are moved. For variable allocated on Stack (Eg: int, float) variable is copied.
In Rust, raw pointers (*const T and *mut T) don't embody ownership semantics directly. However, smart pointers have ownership like
- Box<T>: It represents ownership of a heap-allocated value.
- Rc<T>: It provides reference counting and allows multiple ownership.
- Arc<T>: It's like Rc<T>, but with atomic reference counting, suitable for concurrent access.

C++ (Crash in C++) Rust (No null pointer Exception(Crash) in Rust)
unique_ptr

#include <iostream>
#include <memory>  // unique_ptr
using namespace std;

int main() {
    // Create a unique_ptr to manage the std::string object
    unique_ptr <string> s = make_unique <string>("hello");

    // Transfer ownership to s1
    unique_ptr < string> s1 = move(s);

    // No compile time check.
    // Run time Segmentation fault
    cout << *s;

    std::cout << *s1;

    return 0;
}
                        

fn main() {
    // Box owns the heap-allocated String
    let s = Box::new(String::from("hello")); 

    // Ownership transferred to s1
    let s1 = s; 

    // Compilation error
    // value borrowed here after move
    // The ownership of the String was moved to s1, 
    //so s is no longer valid to use
    println!("{}", s);

    // The String is still valid through s1
    println!("{}", s1);
} // Box goes out of scope, 
// and the String is deallocated automatically