Course contentsShow
← Rust
Lesson 1398 of 1,91012. Unsafe Rust and Low-Level AccessFree lesson

Converting Raw Pointers to References

You will implement runtime checks to safely promote raw pointers back into typed, borrowed references.

In this lesson, you will learn how to safely bridge the gap between raw pointers and Rust's strict reference system by implementing runtime validation checks.

When you hold a raw pointer (*const T or *mut T), Rust effectively "takes its hands off the wheel." The compiler cannot guarantee that the pointer is non-null, properly aligned, or pointing to initialized memory. Converting such a pointer into a reference (&T) is an unsafe operation because the developer must manually guarantee that the memory is valid for the duration of the reference's lifetime.

To perform this conversion safely, we must implement runtime checks before entering the unsafe block.

The Validation Pattern

Before dereferencing, you must verify the pointer's state. A common pattern involves checking for nullity and alignment:

fn safe_cast<'a, T>(ptr: *const T) -> Option<&'a T> {
    // 1. Check if the pointer is null
    if ptr.is_null() {
        return None;
    }

    // 2. Check alignment (essential for undefined behavior prevention)
    if (ptr as usize) % std::mem::align_of::<T>() != 0 {
        return None;
    }

    // 3. Promote to reference within an unsafe block
    // We assume the caller ensures the memory is initialized and immutable
    unsafe { Some(&*ptr) }
}

Why Runtime Checks Matter

In "Unsafe Rust," the primary danger is triggering Undefined Behavior (UB). If you convert a misaligned pointer to a reference, the compiler may optimize assuming the pointer is correctly aligned, leading to silent memory corruption or crashes. By performing these checks, you transform an unchecked, dangerous raw pointer into a checked Option<&T>, effectively creating a "safe gateway" into your low-level code.

Always remember: the unsafe block is only for the dereference itself—the logic that proves the pointer is safe to use should live in the safe code surrounding it.

Key Takeaway: Never convert a raw pointer to a reference without first verifying that it is non-null, correctly aligned, and points to valid, initialized memory.