Ownership and Borrowing
# CHAPTER 10
Ownership and Borrowing
1. Chapter Introduction
Welcome to the most important chapter in this entire course. Ownership is Rust's defining feature. It is the magic mechanism that allows Rust to guarantee memory safety and thread safety without relying on a slow Garbage Collector. If you don't understand Ownership, you cannot write Rust. It will feel like the compiler is constantly fighting you. Let's demystify it completely.2. Learning Objectives
By the end of this chapter, you will be able to:- Understand the 3 Rules of Ownership.
- Differentiate between Stack and Heap memory.
-
Understand Move semantics (why
a = binvalidatesb).
-
Use the
.clone()method.
- Pass complex data into functions without destroying it.
3. Stack vs Heap Memory
To understand Ownership, you must understand where data lives.-
The Stack: Fast, organized memory. Data must have a known, fixed size at compile time (like integers
i32or booleans). When a function ends, Stack data is instantly popped off and deleted.
-
The Heap: Slower, massive memory. Used for data that can grow or shrink (like a user's text
String). The OS finds a free space, stores the data, and gives your program a Pointer (the address) to find it.
*When you are done with Heap memory, it MUST be cleaned up, or your server runs out of RAM (Memory Leak).* Java uses a Garbage Collector to clean it. C requires you to manually call free(). Rust uses Ownership.
4. The 3 Rules of Ownership
Rust's compiler (specifically the Borrow Checker) strictly enforces these three rules:- 1. Each value in Rust has a variable that is called its *owner*.
- 2. There can only be ONE owner at a time.
- 3. When the owner goes out of scope (e.g., the function ends), the value will be automatically dropped (deleted from memory).
5. Move Semantics (Transferring Ownership)
Let's look at simple Stack data (Integers).Now let's look at Heap data (Strings).
Why did this happen?
If s1 and s2 both pointed to the same Heap memory, when the function ends, Rust would try to delete the memory twice (a "Double Free" vulnerability, which crashes systems).
To prevent this, Rust enforces Rule #2: Only ONE owner. When we wrote s2 = s1, s1 handed over ownership and immediately became invalid.
Visualizing Ownership Transfer:
s1 (owner of "Hello") -> let s2 = s1; -> s1 ❌ (Invalid) -> s2 ✅ (New Owner)
6. Cloning (Deep Copy)
If you truly want two separate copies of a String on the Heap, you must explicitly tell Rust to duplicate the data using.clone().
*(Warning: Cloning is slow. Use it sparingly.)*
7. Ownership and Functions
Passing a variable to a function transfers ownership!Wait, if passing data to a function destroys our access to it, how do we ever reuse variables?! We don't want to pass ownership. We just want to let the function *look* at the data temporarily. This is called Borrowing.
8. Mini Project: Memory-Safe String Manager
9. Common Mistakes
-
Assuming Strings act like Integers: You can do
let y = x;with integers because they live on the Stack and copy instantly. You cannot do this withString,Vector, or custom Structs without moving ownership.
-
Using a variable after moving it: This is the #1 error beginners face. The compiler will say "value borrowed here after move". You must either
.clone()it, or use References (next chapter).
10. Best Practices
-
Respect the Compiler: When the compiler gives you an ownership error, don't just throw
.clone()at it to shut it up. Think about *who* should actually own the data.
11. Exercises
-
1.
Create a
Stringinsidemain.
- 2. Assign it to a new variable.
-
3.
Try to
println!the first variable. Read the compiler error carefully.
-
4.
Fix the code using
.clone().
12. MCQs with Answers
Which of the following is NOT one of Rust's Ownership rules?
Integers and Booleans are stored where in memory?
Dynamic, growable data like String is stored where?
What happens when you do let s2 = s1; where s1 is a String?
Why does Rust invalidate s1 in the previous scenario?
What method forces Rust to duplicate Heap data so both variables are valid?
If you pass a String into a function print_word(s: String), what happens to the String in the calling function?
What happens to Heap data when its owner goes out of scope?
Which of the following data types Implements the "Copy" trait, meaning it copies instead of moving?
What is the name of the Rust compiler feature that enforces ownership?
13. Interview Questions
- Q: Explain Rust's Ownership rules and how they replace traditional Garbage Collection.
- Q: What is the difference between a Copy and a Move in Rust? Provide examples of data types for each.
14. FAQs
- Is ownership slow? No! Ownership checks happen entirely during *Compile Time*. At runtime, your program runs at maximum speed with zero overhead.
15. Summary
Ownership is the architectural masterpiece of Rust. By enforcing that every piece of heap memory has exactly one owner, Rust safely deletes memory the exact millisecond the owner goes out of scope. This prevents memory leaks and security vulnerabilities. However, constantly handing ownership back and forth to functions is exhausting.16. Next Chapter Recommendation
There must be a better way to let a function look at a string without taking ownership of it! In Chapter 11: References and Slices, we will learn how to "Borrow" data using the& symbol.