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

The Lifetime of Raw Pointers

You will manage the manual tracking of lifetimes when pointers escape the scope of Rust's standard borrow checking.

In this lesson, you will learn how to manually manage the conceptual lifetime of raw pointers when they escape the constraints of Rust’s borrow checker.

When you convert a reference to a raw pointer (using as *const T or as *mut T), you effectively "strip" away the borrow checker's ability to track that data’s validity. Unlike references, which carry an explicit lifetime 'a that the compiler enforces, raw pointers are essentially memory addresses with no inherent duration. It is your responsibility as the programmer to ensure that the memory being pointed to remains initialized and allocated for as long as the pointer exists.

Tracking Lifetimes Manually

Because raw pointers don't automatically invalidate, it is easy to fall into the trap of using a "dangling" pointer. Consider a scenario where you store a pointer to a stack-allocated variable:

let ptr: *const i32;
{
    let value = 42;
    ptr = &value as *const i32;
} // 'value' is dropped here!
// ptr is now dangling; dereferencing it is Undefined Behavior.
unsafe {
    println!("{}", *ptr); // DANGER: Use-after-free
}

To safely manage this, you must treat raw pointers as having a "logical lifetime" that you maintain in your design documentation or through strict structural patterns. If you need to pass a pointer across scopes, you must ensure the data it points to is kept alive—perhaps by holding an Arc or Box elsewhere—or by strictly bounding the pointer's usage to the scope of the underlying owner.

The Responsibility of the Programmer

When working with raw pointers, you are taking over the role of the compiler. You must guarantee that:

  1. The memory pointed to has not been deallocated.
  2. The data has not been dropped.
  3. The pointer is not null (if you intend to dereference it).

Because the compiler cannot "see" the relationship between the pointer and the data, it cannot prevent you from creating these leaks or dangling pointers. Always document the intended lifetime of the memory you point to as clearly as if you were writing a function signature with explicit lifetime parameters.

Key Takeaway: Raw pointers lack the automatic lifetime tracking of references, requiring you to manually ensure the pointed-to memory remains valid throughout the entire duration of the pointer's use.