codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🦀

Rust

31 / 58 topics
29Memory Management30Smart Pointers31Unsafe Rust
Tutorials/Rust/Unsafe Rust
🦀Rust

Unsafe Rust

Updated 2026-05-15
10 min read

Unsafe Rust

Rust is known for its strong emphasis on memory safety, which is achieved through its ownership model and borrowing rules. However, there are times when you might need to bypass these safety checks for performance reasons or to interact with low-level system APIs. This tutorial will explore the concept of unsafe blocks and operations in Rust.

Introduction

Rust's type system and safety guarantees make it a great language for writing safe and efficient code. However, sometimes you need to perform operations that could potentially lead to memory unsafety, such as dereferencing raw pointers or calling functions with undefined behavior. To allow these operations, Rust provides the unsafe keyword.

When you use the unsafe keyword, you are telling the Rust compiler that you understand the risks involved and are taking responsibility for ensuring that the code is safe. This means that using unsafe blocks should be done with caution and only when absolutely necessary.

Concept

Unsafe blocks in Rust allow you to perform operations that would otherwise be disallowed by the language's safety guarantees. These operations include:

  • Dereferencing raw pointers
  • Calling functions or methods marked as unsafe
  • Implementing traits for foreign types
  • Accessing or modifying a mutable static variable

To use unsafe blocks, you must wrap the code in an unsafe block and then call any unsafe operation within that block. Here's the basic syntax:

Rust
1unsafe {
2 // Unsafe operations go here
3}

Examples

Dereferencing Raw Pointers

Raw pointers are similar to pointers in other languages like C or C++. They allow you to bypass Rust's safety checks and directly manipulate memory. However, using raw pointers requires careful handling to avoid undefined behavior.

Here's an example of how to use raw pointers:

Rust
1fn main() {
2 let mut num = 5;
3 let r1 = &num as *const i32;
4 let r2 = &mut num as *mut i32;
5
6 unsafe {
7 println!("r1 is: {}", *r1);
8 println!("r2 is: {}", *r2);
9 }
10}

In this example, we create a mutable variable num and obtain two raw pointers to it: one immutable (*const i32) and one mutable (*mut i32). We then use an unsafe block to dereference these pointers and print their values.

Calling Unsafe Functions

Some functions in Rust are marked as unsafe, meaning they can perform operations that could lead to undefined behavior. To call such a function, you must wrap the call in an unsafe block.

Here's an example of calling an unsafe function:

Rust
1unsafe fn dangerous_divide(a: i32, b: i32) -> i32 {
2 a / b
3}
4
5fn main() {
6 let result = unsafe { dangerous_divide(10, 2) };
7 println!("Result is: {}", result);
8}

In this example, we define an unsafe function dangerous_divide that performs division. We then call this function within an unsafe block in the main function.

Implementing Traits for Foreign Types

When working with foreign types (types defined in other languages), you might need to implement traits for these types. This can be done using unsafe blocks.

Here's an example of implementing a trait for a foreign type:

Rust
1extern crate libc;
2
3use std::fmt;
4use libc::c_int;
5
6unsafe impl fmt::Debug for c_int {
7 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8 write!(f, "libc::c_int({})", *self)
9 }
10}
11
12fn main() {
13 let num = 42 as c_int;
14 println!("{:?}", num);
15}

In this example, we implement the Debug trait for the foreign type libc::c_int. We use an unsafe block to define the implementation.

What's Next?

Now that you have a good understanding of unsafe blocks and operations in Rust, you can explore more advanced topics such as generics. Generics allow you to write code that is generic over types, providing flexibility and reusability. Stay tuned for our next tutorial on generics!

Info

Remember, using unsafe blocks should be done with caution and only when necessary. Always ensure that the operations within an unsafe block are safe to avoid undefined behavior.


PreviousSmart PointersNext Generics

Recommended Gear

Smart PointersGenerics