Skip to content

String::from_raw_parts

String methods · Strings

Level: reference · for working programmers

One line: Rebuilds a String from a pointer, a length and a capacity — unsafe, and the counterpart of into_raw_parts.

pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String

Stable since 1.0.0. unsafe — the caller carries the invariant described below.

The contract is demanding, and every clause matters:

  • the pointer must come from a String (or a Vec<u8>) allocated by the same allocator
  • length and capacity must be exactly the values that String had
  • the first length bytes must be valid UTF-8

Getting capacity wrong corrupts the allocator on drop, because the deallocation is sized. This is not a place to approximate.

The only routine use is the round trip: into_raw_parts to hand ownership across an FFI boundary as three plain integers, then from_raw_parts to take it back and let Rust drop it normally. Reconstructing a String from a pointer that came from malloc, or from C, is not sound — free it with whatever allocated it.

Example

string_from_raw_parts.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.

fn main() {
    let s = String::from("héllo");
    println!("{s:?} len {} capacity {}", s.len(), s.capacity());

    // The round trip: exactly the three values that came out.
    let (ptr, len, cap) = s.into_raw_parts();
    println!("carried across as {len} and {cap}");
    let back = unsafe { String::from_raw_parts(ptr, len, cap) };
    println!("{back:?}");

    // A Vec<u8> allocated by Rust works too, if the bytes are valid UTF-8.
    let mut v = Vec::from("hi".as_bytes());
    v.reserve_exact(6);
    let (p, l, c) = (v.as_mut_ptr(), v.len(), v.capacity());
    std::mem::forget(v);
    let rebuilt = unsafe { String::from_raw_parts(p, l, c) };
    println!("{rebuilt:?} capacity {}", rebuilt.capacity());
}

Verified output of string_from_raw_parts.rs — regenerated by tools/run_examples.py, never hand-typed.

"héllo" len 6 capacity 6
carried across as 6 and 6
"héllo"
"hi" capacity 8

See also

String::from_raw_parts in the standard library ↗

Po polsku

To unsafe nie jest tu ozdobą: za trzy warunki naraz ręczy wywołujący, a nie kompilator — wskaźnik musi pochodzić z tego samego alokatora, length i capacity muszą być dokładnie tymi liczbami, które miał pierwotny String, a pierwsze length bajtów musi być poprawnym UTF-8. Najgroźniejsza pomyłka to potraktowanie capacity jako „mniej więcej tyle”: zwalnianie pamięci w Ruscie jest rozmiarowane (sized deallocation), więc zła pojemność psuje alokator dopiero przy wypuszczeniu zasobu, daleko od miejsca błędu. Jedyne rutynowe zastosowanie to podróż w obie strony — into_raw_parts przenosi własność przez granicę FFI jako trzy zwykłe liczby, a from_raw_parts odbiera ją z powrotem, żeby Rust mógł normalnie zwolnić bufor. Wskaźnika z malloc ani z kodu C tu wstawiać nie wolno: pamięć zwalnia ten, kto ją przydzielił.

Szukaj po polsku: własność przez granicę FFI · unsafe w Ruscie · alokator pamięci · rust String::from_raw_parts · rust sized deallocation capacity mismatch