Skip to content
Zurück zu den Lernmaterialien

Modul 11 — Smart Pointer & der Heap

6. September 2026~3 min read
Lektion von 0/ abgeschlossen
Modul 11 — Smart Pointer & der Heap

Box: der Zeiger auf den Heap

Bisher lebten deine Werte auf dem Stack — mit bekannter, fester Größe. Box verschiebt den Inhalt auf den Heap; auf dem Stack bleibt nur ein dünner Zeiger, der den Wert besitzt:

fn main() {
    let gross = Box::new([0u8; 4096]);

    println!("erstes Byte: {}", gross[0]);
    println!("Länge: {}", gross.len());
}

Dank Deref verhält sich der Box-Zeiger wie der Wert selbst: Index-Zugriff, Methoden, Dereferenzierung mit * — alles funktioniert direkt. Beim Drop wird der Heap-Speicher freigegeben. Ein Besitzer, eine Freigabe — dein Ownership-Modell, nur mit Umleitung über den Heap.

Zwei klassische Einsatzfälle:

  • Rekursive Typen — eine verkettete Liste enthält sich selbst; ohne Box kennt der Compiler die Größe nicht (E0072). Der Box-Zeiger hat feste Größe und bricht den Kreis. Die Übung baut genau das.
  • Einheitliche Fehler — ein Tool, das Datei- UND Parse-Fehler wirft:
use std::error::Error;

fn alter_von(zeile: &str) -> Result<u32, Box<dyn Error>> {
    let (_, wert) = zeile
        .split_once('=')
        .ok_or("Zeile ohne Gleichheitszeichen")?;
    Ok(wert.trim().parse::<u32>()?)
}

fn main() {
    println!("{:?}", alter_von("alter=30"));
}

Box<dyn Error> ist der pragmatische Fehlertyp für Programme: jede konkrete Fehlerart passt hinein, ? konvertiert automatisch.

Wann Box?

  • Rekursive Datentypen — der Größe-Kreisbruch
  • Große Werte, die du verschieben willst, ohne zu kopieren
  • Trait-Objekte — die Fehler-Box mit dyn Error versteckt die Größe hinter einem Zeiger

Übung: die rekursive Liste

🧩 Übung m11-l1-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

✅ Wichtige Erkenntnisse

Haken setzen, um deinen Lernfortschritt zu markieren:

    Lektion von 0/ abgeschlossen
    Modul 11 — Smart Pointer & der Heap

    Rc: Besitz teilen

    Box hat genau einen Besitzer. Manchmal brauchen denselben Wert aber mehrere: eine Konfiguration, die zwei Module lesen; ein Knoten, auf den mehrere Datenstrukturen zeigen. Rc (Reference Counted) erlaubt mehrere Besitzer — zur Laufzeit gezählt:

    use std::rc::Rc;
    
    fn main() {
        let konfig = Rc::new(vec![10, 20, 30]);
    
        let kopie_a = Rc::clone(&konfig);
        let kopie_b = Rc::clone(&konfig);
    
        println!("a-Summe: {}", kopie_a.iter().sum::<u32>());
        println!("Besitzer: {}", Rc::strong_count(&konfig));
    }
    

    Rc::clone kopiert NICHTS — es erhöht nur den Zähler. Alle drei Bindungen zeigen auf denselben Heap-Wert; fällt der letzte Besitzer weg, wird er freigegeben. strong_count sagt dir, wie viele es gerade sind.

    Der Preis: Rc-Inhalte sind nur lesbar. Mit mehreren Besitzern könnte eine Änderung über einen Zeiger invalidieren, was ein anderer gerade liest — genau das verbietet Rusts Aliasing-Regel. Für Mutation braucht es den nächsten Baustein.

    Und Rc bleibt zuhause: sein Zähler ist nicht atomar, also ist Rc ausdrücklich nicht thread-safe. Für Threads gibt es Arc — dasselbe Muster mit atomarem Zähler (Modul 12).

    📝 Schnellprüfung

    Was kostet Rc::clone(&konfig) zur Laufzeit?

    Übung: geteilter Besitz

    🧩 Übung m11-l2-e1

    🔮 Vorhersage: Was passiert beim Ausführen?

    Editor wird geladen…
    KI-Tutor (sokratisch — keine Komplettlösungen)

    ✅ Wichtige Erkenntnisse

    Haken setzen, um deinen Lernfortschritt zu markieren:

      Lektion von 0/ abgeschlossen
      Modul 11 — Smart Pointer & der Heap

      RefCell: Mutation zur Laufzeit

      Die Borrow-Regeln gelten zur Compile-Zeit — meistens gut, manchmal zu streng: Ein Logger wird von vielen Stellen geteilt und darf trotzdem wachsen. RefCell verlagert die Prüfung in die Laufzeit:

      use std::cell::RefCell;
      
      fn main() {
          let log = RefCell::new(Vec::new());
      
          log.borrow_mut().push(String::from("start"));
      
          {
              let lesend = log.borrow();
              println!("Einträge: {}", lesend.len());
          }
      
          log.borrow_mut().push(String::from("ende"));
          println!("{:?}", log.borrow());
      }
      

      borrow() leiht lesend (beliebig oft), borrow_mut() exklusiv. Die Regel bleibt dieselbe — Shared XOR Exclusive — nur dass RefCell sie zählt: ein Konflikt paniziert sofort, mit präziser Meldung. Der innere Block gibt den lesenden Borrow zurück, bevor borrow_mut() kommt.

      Die Kombo aus beiden Welten ist der Klassiker: Rc + RefCell — Rc teilt den Besitz, RefCell erlaubt die Änderung durch den gemeinsamen Handle. Geteilter, veränderlicher Zustand ohne unsafe.

      Runtime-Borrows im Griff

      • borrow() = lesender Zähler hoch; borrow_mut() = exklusiv, paniziert bei Konflikt
      • try_borrow_mut() liefert Result statt Panic — für abfangbare Konflikte
      • Rc + RefCell = geteilter, veränderlicher Zustand (single-threaded)

      Übung: der Runtime-Borrow

      🧩 Übung m11-l3-e1

      🔮 Vorhersage: Was passiert beim Ausführen?

      Editor wird geladen…
      KI-Tutor (sokratisch — keine Komplettlösungen)

      ✅ Wichtige Erkenntnisse

      Haken setzen, um deinen Lernfortschritt zu markieren:

        Lektion von 0/ abgeschlossen
        Modul 11 — Smart Pointer & der Heap

        Mini-Projekt: der geteilte Tracker

        Das Szenario vorweg — dann baust du die Lösung:

        🏢 Praxis-Szenario: Die Ausgabenliste, die jeder sehen darf

        Dein Team bucht Ausgaben (Server, Domain, Kaffee) in einer geteilten Liste. Bisher: drei Kollegen, drei eigene Kopien der Liste, dreimal wöchentlich manuell zusammenführen — und dreimal pro Monat falsche Summen. Die Anforderung: EINE Liste im Speicher, auf die mehrere Stellen schreiben und lesen, ohne dass sich jemand Kopien zieht oder die Summe aus dem Takt kommt.

        🧩 Übung m11-l4-e1

        🔮 Vorhersage: Was passiert beim Ausführen?

        Editor wird geladen…
        KI-Tutor (sokratisch — keine Komplettlösungen)

        Was du in Modul 11 geschafft hast

        • Box: Heap mit einem Besitzer — inklusive Rekursions-Ausweg und dyn Error
        • Rc: geteilter Besitz per Zähler — read-only, billig zu klonen
        • RefCell: Borrow-Regeln zur Laufzeit; Rc + RefCell = geteilter veränderlicher Zustand
        • Ein Tracker mit EINER Quelle der Wahrheit

        ✅ Wichtige Erkenntnisse

        Haken setzen, um deinen Lernfortschritt zu markieren:

          Modul-Checkpoint

          Checkpoint: Modul 11

          Bestehensgrenze: 80 %. Der Versuch wird bewertet und zählt für das Modul-Gate.

          Bereit, dein Wissen zu testen?

          Probiere unsere Übungsprüfungen mit Hunderten von realistischen Fragen aus.

          Üben starten →

          This site uses essential cookies for Stripe payments. No tracking cookies.