String::from_raw_parts¶
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.
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 aVec<u8>) allocated by the same allocator lengthandcapacitymust be exactly the values thatStringhad- the first
lengthbytes 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.
See also¶
String::into_raw_parts— where the three values come fromString::leak— handing out the memory and never taking it backstr::as_ptr— a pointer that does NOT carry ownershipString::from_utf8_unchecked— the same UTF-8 obligation, without the pointer
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