What is different in Rust in regards and why is Rust safer than C

🧠 General Idea

  • C gives you full control over memory — which is powerful, but also dangerous.
  • Rust aims to give you similar performance and control as C, but without the memory safety issues — thanks to a strict compiler and ownership system.

🔥 Dangers in C (Why It’s Unsafe)

C gives the programmer full freedom — and that includes the freedom to shoot yourself in the foot.

Here are the most common problems in C:

1. Dangling Pointers

int* foo() {
    int x = 42;
    return &x; // BAD: x is on the stack, destroyed after return
}

➡ You just returned a pointer to invalid memory.


2. Use-After-Free

int* x = malloc(sizeof(int));
free(x);
*x = 5; // undefined behavior: accessing freed memory

3. Double Free

free(x);
free(x); // undefined behavior again

4. Buffer Overflows

char arr[10];
arr[20] = 'x'; // writes past the array, causes undefined behavior

➡ These bugs often lead to crashes, data corruption, or security vulnerabilities (e.g., buffer overflow exploits).


🦀 How Rust Prevents These Issues

Rust uses a strict compile-time system to prevent these errors without a garbage collector.

Key Safety Features in Rust:


✅ 1. Ownership and Borrowing

Rust enforces ownership rules:

fn main() {
    let s = String::from("hello");
    let t = s; // s is moved, you can no longer use s
}

➡ You can’t have two owners of the same memory by default — no double-free, no use-after-free.

If you want to share, you must borrow with clear rules:

  • &T → immutable borrow
  • &mut T → mutable borrow

And you can’t mix mutable and immutable borrows at the same time.


✅ 2. No Null or Dangling Pointers

Rust has no null pointers by default. Instead, you use:

let maybe_value: Option<i32> = Some(5); // or None

➡ This forces you to handle the "null case" explicitly.


✅ 3. Memory is Freed Automatically — But Predictably

Rust uses RAII (Resource Acquisition Is Initialization):

fn main() {
    let s = String::from("hello"); // allocated
} // s goes out of scope, automatically freed

➡ No need for free() and no risk of memory leaks or double frees.


✅ 4. Array Bounds Checking

In safe Rust:

let arr = [1, 2, 3];
arr[10]; // compile-time or run-time panic

➡ Buffer overflows are caught.

(You can use unsafe Rust, but that’s opt-in and limited to small, controlled areas.)


🔍 Why Rust is Safer than C (Summary Table)

ProblemC (unsafe)Rust (safe)
Dangling pointersEasy to createImpossible in safe code
Use-after-freeEasy to mess up manuallyOwnership model prevents it
Double freeHappens if you forget bookkeepingAutomatically managed via ownership
Buffer overflowNo bounds checksBounds-checked arrays
Null pointersPointers can be NULLUse Option<T> instead, enforced at compile time
Manual memory mgmt.Yes, error-proneNo manual free() needed

🧪 Conclusion

  • C is powerful, but puts the burden of correctness on the programmer.
  • Rust is also powerful, but builds memory safety into the language through its ownership, borrowing, and type system.
  • It eliminates entire classes of bugs at compile time that C developers need to fight manually.

Would you like a side-by-side code comparison of the same memory bug in C vs. how Rust prevents it?

Vikash Chauhan

C# & .NET experienced Software Engineer with a demonstrated history of working in the computer software industry.

Post a Comment

Previous Post Next Post

Contact Form