Course contentsShow
← Rust
Lesson 145 of 1,9102. The Ownership ModelFree lesson

Transferring Ownership through FFI

Manage memory when interfacing with external C libraries that do not use Rust's ownership model.

In this lesson, you will learn how to safely hand over memory management responsibilities from Rust to an external C library.

When you work with Foreign Function Interface (FFI), you are stepping outside of Rust’s "safety net." C libraries don't know about the Drop trait or Rust's borrow checker. If you pass a pointer to a Rust-allocated buffer to C, the C library might try to free that memory later, or it might lose track of it entirely, leading to a memory leak.

To handle this, we use the "hand-off" pattern. The goal is to make the C library the "owner" of the data.

The Hand-off Strategy

If you have a Rust-allocated Vec<u8> and you want a C library to take control of it, you must perform two steps:

  1. Forget the Rust ownership: Use std::mem::forget to ensure the Rust side doesn't call drop() on the memory when the Vec goes out of scope.
  2. Transfer the pointer: Pass the raw pointer to the C function.
fn transfer_to_c(data: Vec<u8>) {
    // Get the raw parts of the vector
    let (ptr, len, cap) = data.into_raw_parts();
    
    // Pass these to the C library
    unsafe {
        c_library_take_ownership(ptr, len, cap);
    }
    
    // We do NOT call drop(data) or let it fall out of scope 
    // to reclaim the memory, because C now owns it.
}

Why this matters

In the code above, into_raw_parts() breaks the Vec into its raw components. Crucially, it stops the Vec from cleaning itself up. The C library must be designed to eventually call free() on that exact pointer. If the C library doesn't have a matching "destroy" function, your memory will leak.

Because the C library cannot verify if the memory is still valid, you must be absolutely certain that you are not keeping any references (borrows) to that data in Rust after the hand-off. Once you hand it to C, Rust considers that memory gone forever.

Key Takeaway: To transfer ownership to FFI, you must explicitly disable Rust’s automatic cleanup using std::mem::forget or into_raw_parts and document exactly which C function is responsible for freeing that memory.