Skip to content

String::leak

String methods · Strings

Level: reference · for working programmers

One line: Consumes the String and returns a &'static mut str — the memory is never freed, and that is the point.

pub fn leak<'a>(self) -> &'a mut str

Stable since 1.72.0.

It gives up ownership to nobody. The allocation lives until the process exits, which is what buys the 'static lifetime: the reference is valid forever because nothing will ever invalidate it.

That is a legitimate trade for values that live as long as the program anyway — a configuration string read at startup and referenced everywhere, or a name that has to satisfy a 'static bound in a library API. It is a bug when it happens per request or per iteration, where it is simply an unbounded memory leak.

The reference is &'static mut str, so it is unique and mutable; it can be reborrowed as &'static str.

Box::leak(s.into_boxed_str()) is the older spelling of the same thing. Neither can be undone — there is no un-leak, short of reconstructing through from_raw_parts with the exact capacity, which leak has already discarded.

Example

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

fn main() {
    let built = format!("config-{}", 42);
    let forever: &'static str = String::leak(built);
    println!("{forever:?}");

    // 'static, so it satisfies a bound that a borrowed String could not.
    fn needs_static(s: &'static str) -> usize { s.len() }
    println!("{}", needs_static(forever));

    // The reference is mutable before you narrow it.
    let mut_ref: &'static mut str = String::from("hello").leak();
    mut_ref.make_ascii_uppercase();
    println!("{mut_ref:?}");

    // The older spelling.
    let boxed: &'static str = Box::leak(String::from("also static").into_boxed_str());
    println!("{boxed:?}");

    // The bug shape: leaking per iteration is an unbounded leak.
    let leaked_total: usize = (0..3).map(|i| String::leak(format!("item{i}")).len()).sum();
    println!("{leaked_total} bytes leaked deliberately");
}

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

"config-42"
9
"HELLO"
"also static"
15 bytes leaked deliberately

See also

String::leak in the standard library ↗

Po polsku

Nazwa jest dosłowna i celowo prowokacyjna: leak to wyciek pamięci popełniony umyślnie. Metoda pochłania łańcuch znaków i zwraca &'static mut str — bufor nie zostanie zwolniony aż do zakończenia procesu, i właśnie stąd bierze się statyczny czas życia (static lifetime): referencja jest ważna zawsze, bo nic nigdy jej nie unieważni. To uczciwy interes dla danych, które i tak żyją tyle co program — konfiguracja wczytana przy starcie, nazwa, którą trzeba wcisnąć w API żądające 'static — i zwyczajny błąd tam, gdzie powtarza się raz na żądanie albo raz na obrót pętli; ostatnia linijka przykładu wycieka 15 bajtów w trzech obrotach i nic tego nie posprząta. Odwrotu nie ma, bo leak wyrzuca pojemność, więc nawet from_raw_parts już nie uratuje sytuacji — gdy chcesz zachować możliwość oddania pamięci, sięgnij po into_raw_parts, które wszystkie trzy liczby zwraca.

Szukaj po polsku: celowy wyciek pamięci · statyczny czas życia · rust String leak · rust Box::leak static str · rust static lifetime bound