Review of Program Memory
Programs allocate memory in two ways:
-
Stos: ciągły obszar pamięci dla zmiennych lokalnych.
- Wartości mają stałe rozmiary znane w czasie kompilacji.
- Niezwykle szybki: wystarczy przesunąć wskaźnik stosu.
- Łatwy w zarządzaniu: podąża za wywołaniami funkcji.
- Świetna lokalność pamięci.
-
Sterta: Przechowywanie wartości poza wywołaniami funkcji.
- Wartości mają dynamiczne rozmiary określone w czasie wykonywania.
- Nieco wolniejsza niż stos: potrzebne trochę księgowości.
- Brak gwarancji lokalności pamięci.
Przykład
Creating a String puts fixed-sized metadata on the stack and dynamically sized data, the actual string, on the heap:
fn main() {
let s1 = String::from("Hello");
}
-
Wspomnij, że
Stringjest oparty oVec, więc ma pojemność i długość, i jeżeli jest mutowalny to może rosnąć poprzez realokację na stercie. -
Jeżeli uczniowie o to zapytają to możesz wspomnieć, że pamięć na stercie jest alokowana za pomocą alokatora systemowego I własny alokator może być zaimplementowany używając API alokatora
More to Explore
We can inspect the memory layout with unsafe Rust. However, you should point out that this is rightfully unsafe!
fn main() {
let mut s1 = String::from("Hello");
s1.push(' ');
s1.push_str("world");
// DON'T DO THIS AT HOME! For educational purposes only.
// String provides no guarantees about its layout, so this could lead to
// undefined behavior.
unsafe {
let (ptr, capacity, len): (usize, usize, usize) = std::mem::transmute(s1);
println!("ptr = {ptr:#x}, len = {len}, capacity = {capacity}");
}
}