Stack Memory
Creating a String puts fixed-sized data on the stack and dynamically sized data on the heap:
1. fn main() {
2. let s1 = String::from("Hello");
3. }

- Mention that a
Stringis backed by aVec, so it has a capacity and length and can grow if mutable via reallocation on the heap. - If students ask about it, you can mention that the underlying memory is heap allocated using the System Allocator and custom allocators can be implemented using the Allocator API
- We can inspect the memory layout with
unsafecode. However, you should point out that this is rightfully unsafe!
1. fn main() {
2. let mut s1 = String::from("Hello");
3. s1.push(' ');
4. s1.push_str("world");
5. // DON'T DO THIS AT HOME! For educational purposes only.
6. // String provides no guarantees about its layout, so this could lead to
7. // undefined behavior.
8. unsafe {
9. let (capacity, ptr, len): (usize, usize, usize) = std::mem::transmute(s1);
10. println!("ptr = {ptr:#x}, len = {len}, capacity = {capacity}");
11. }
12. }
