Strings and Text Processing

String

String (std::string::String) is a growable, mutable, heap-allocated, UTF-8 encoded text buffer owned by a single binding.

Memory Layout of String

Internally, String is a wrapper around a Vec<u8> (struct String { vec: Vec<u8> }) that enforces the invariant that its bytes are always valid UTF-8. On a 64-bit platform, a String occupies 24 bytes on the stack (ptr, len, capacity) pointing to a contiguous byte buffer on the heap:

Stack (`String`, 24 bytes)           Heap Buffer (8 bytes allocated)
+----------------+                   +---+---+---+---+---+---+---+---+
| ptr      (8 B) +-----------------> | R | u | s | t |   |   |   |   |
| len      = 4   |                   +---+---+---+---+---+---+---+---+
| capacity = 8   |                     0   1   2   3   4   5   6   7
+----------------+
  • ptr: Non-null pointer to the heap-allocated byte buffer (or a dangling aligned pointer when capacity == 0).
  • len: Number of UTF-8 bytes currently stored in the string (0 <= len <= capacity).
  • capacity: Total number of bytes allocated on the heap before reallocation is required.

Constructing a String

Constructor / Method Heap Allocation Behavior Typical Use Case
String::new() Zero heap allocation (capacity == 0) Starting an empty buffer
String::with_capacity(n) Pre-allocates n bytes upfront Building a string of known approximate byte length
String::from("text") / "text".to_owned() Allocates and copies the string slice Promoting a &str into an owned String
String::from_utf8(vec) Reuses Vec<u8> buffer with zero copy after validating UTF-8 Converting a byte vector read from I/O into a String
String::from_utf8_lossy(slice) Returns Cow::Borrowed(&str) if valid UTF-8, or allocates Cow::Owned(String) replacing invalid sequences with U+FFFD (``) Displaying potentially malformed external byte streams
fn main() {
    let mut s = String::with_capacity(16);
    println!("Initial: len={}, cap={}", s.len(), s.capacity());

    s.push_str("Rust 2024");
    println!("After push_str: '{s}' (len={}, cap={})", s.len(), s.capacity());

    // Zero-copy conversion from a valid UTF-8 `Vec<u8>`:
    let raw_bytes = vec![0x4F, 0x4B]; // "OK"
    let from_vec = String::from_utf8(raw_bytes).unwrap();
    println!("From Vec<u8>: {from_vec}");
}
Initial: len=0, cap=16
After push_str: 'Rust 2024' (len=9, cap=16)
From Vec<u8>: OK

Deref Coercion from String to &str

String implements Deref<Target = str>, which means &String automatically coerces to &str and inherits every read-only method defined on str (such as .trim(), .lines(), .starts_with(), and .split()).