notes

Log | Files | Refs | README

string_vs_str.md (3454B)


      1 # String vs Str
      2 
      3 Here is how `String` source code look like:
      4 
      5 ```rust
      6 #[derive(PartialEq, PartialOrd, Eq, Ord)]
      7 #[stable(feature = "rust1", since = "1.0.0")]
      8 #[lang = "String"]
      9 pub struct String {
     10     vec: Vec<u8>,
     11 }
     12 ```
     13 
     14 In Rust, String is implemented as a wrapper around a `Vec<u8>` because it is
     15 designed to be a dynamically growable, heap-allocated buffer of UTF-8 encoded
     16 bytes. The standard library leverages the existing `Vec` type to manage the
     17 string's underlying memory while enforcing specific character encoding rules.
     18 
     19 ## The Stack Layout
     20 
     21 When you create a String, Rust places a small, fixed-size struct on the stack.
     22 On a 64-bit system, this struct is exactly 24 bytes and consists of three
     23 machine-word fields:
     24 
     25 - **Pointer**: A reference pointing to the memory address on the heap where the
     26   actual UTF-8 text data is stored.
     27 
     28 - **Length**: The amount of memory (in bytes) currently being used by the
     29   string's text.
     30 
     31 - **Capacity**: The total amount of heap memory currently allocated for the
     32   string.
     33 
     34 Because this control block is small, moving a String from one variable to
     35 another is incredibly fast. Rust only copies these 24 bytes of metadata on the
     36 stack rather than copying the actual text data on the heap.
     37 
     38 ## String memory allocation
     39 
     40 - **p** is the address of the String object itself, so text keeps the same p the
     41   whole time because it is the same variable.
     42 
     43 - **ptr** is the address of the actual character buffer.
     44 
     45 - **len** is the current string size.
     46 
     47 - **capacity** is how much buffer space is available before another growth is
     48   needed.
     49 
     50 ```rust
     51 fn main() {
     52     let mut text = String::new();
     53     println!("p: {:p} ptr: {:<15?} len: {:2}, capacity: {:2} '{}'", &text, text.as_ptr(), text.len(), text.capacity(), text);
     54 
     55     text.push_str("Hello foo!");
     56     println!("p: {:p} ptr: {:<15?} len: {:2}, capacity: {:2} '{}'", &text, text.as_ptr(), text.len(), text.capacity(), text);
     57 
     58     text.replace_range(6..9, "bar");
     59     println!("p: {:p} ptr: {:<15?} len: {:2}, capacity: {:2} '{}'", &text, text.as_ptr(), text.len(), text.capacity(), text);
     60 
     61     let temp = String::from("The black cat");
     62     println!("{temp}");
     63     println!("p: {:p} ptr: {:<15?} len: {:2}, capacity: {:2} '{}'", &temp, temp.as_ptr(), temp.len(), temp.capacity(), temp);
     64 
     65     text.replace_range(6..9, "qqrq");
     66     println!("p: {:p} ptr: {:<15?} len: {:2}, capacity: {:2} '{}'", &text, text.as_ptr(), text.len(), text.capacity(), text);
     67 
     68     text.replace_range(6..9, "123456");
     69     println!("p: {:p} ptr: {:<15?} len: {:2}, capacity: {:2} '{}'", &text, text.as_ptr(), text.len(), text.capacity(), text);
     70 
     71     text.replace_range(6..9, "12345678901234567890");
     72     println!("p: {:p} ptr: {:<15?} len: {:2}, capacity: {:2} '{}'", &text, text.as_ptr(), text.len(), text.capacity(), text);
     73 
     74 }
     75 ```
     76 
     77 ```rust
     78 p: 0x7ffdcc572770 ptr: 0x1             len:  0, capacity:  0 ''
     79 p: 0x7ffdcc572770 ptr: 0x5de087754ba0  len: 10, capacity: 10 'Hello foo!'
     80 p: 0x7ffdcc572770 ptr: 0x5de087754ba0  len: 10, capacity: 10 'Hello bar!'
     81 The black cat
     82 p: 0x7ffdcc573260 ptr: 0x5de087754bc0  len: 13, capacity: 13 'The black cat'
     83 p: 0x7ffdcc572770 ptr: 0x5de087754ba0  len: 11, capacity: 20 'Hello qqrq!'
     84 p: 0x7ffdcc572770 ptr: 0x5de087754ba0  len: 14, capacity: 20 'Hello 123456q!'
     85 p: 0x7ffdcc572770 ptr: 0x5de087754be0  len: 28, capacity: 40 'Hello 12345678901234567890q!'
     86 ```
     87 
     88 [String and memory allocation](https://rust.code-maven.com/strings-and-memory-allocation)