====== Lyx – Memory Management ====== Lyx bietet volle Kontrolle über den Speicher. Es nutzt kein automatisches Speichermanagement (kein GC), sondern setzt auf eine Kombination aus Stack-Allokation (automatisch) und Heap-Allokation (manuell). ===== 1) Stack-Allokation (Automatisch) ===== Der Stack ist der Standard-Speicherort für lokale Variablen. Er ist extrem schnell, da der Speicher beim Funktionsaufruf reserviert und beim Verlassen automatisch freigegeben wird. Typen auf dem Stack: Primitiven (int, f64, bool), struct und lokale Arrays mit fester Größe. Gültigkeit: Nur innerhalb der Funktion (Scope), in der sie deklariert wurden. fn DoWork() { var x: int64 := 10; // Stack var point: TPoint; // Struct auf dem Stack // Am Ende der Funktion wird der Speicher für x und point sofort frei. } ===== 2) Heap-Allokation (Manuell) ===== Daten, die länger existieren müssen oder deren Größe erst zur Laufzeit feststeht, werden auf dem Heap abgelegt. Typen auf dem Heap: Instanzen von class und dynamische Arrays (array). Keywords: new reserviert Speicher, dispose gibt ihn frei. var p := new Player(); // Allokiert auf dem Heap p.Name := "Lyx-User"; // ... Arbeit mit p ... dispose p; // WICHTIG: Manuelle Freigabe, sonst Memory Leak! ===== 3) Dynamische Arrays ===== Seit v0.2.1 unterstützt Lyx dynamische Arrays als "Fat Pointer" (Adresse + Länge + Kapazität). var list: array := [1, 2, 3]; // Initialisierung auf dem Heap list.push(4); // Vergrößert das Array bei Bedarf PrintInt(list.len()); // Builtin-Funktion für die Länge dispose list; // Gibt den gesamten Array-Buffer frei ===== 4) Null-Safety & Safe Navigation ===== Um "Null Pointer Access"-Abstürze zu minimieren, bietet Lyx moderne Operatoren für Heap-Objekte: Safe Call (?.): Der Aufruf wird nur ausgeführt, wenn das Objekt nicht null ist. Null Coalescing (??): Bietet einen Fallback-Wert. var name := p?.GetName() ?? "Unbekannt"; ===== 5) Best Practices für Lyx ===== Um Speicherfehler zu vermeiden, empfiehlt das Lyx-Team folgende Regeln: ^ Regel ^ Beschreibung ^ | RAII-Muster | Allokiere im Konstruktor (Create), gib frei im Destruktor. | | Stack bevorzugen | Nutze struct statt class, wenn das Objekt die Funktion nicht verlassen muss. | | Dangling Pointers | Setze Pointer nach einem dispose auf null, um Double-Frees zu verhindern. | | Result-Pattern | Nutze std.Result für Operationen, die fehlschlagen könnten, statt null zurückzugeben. | ===== 6) Ausblick: Smart Pointers (Roadmap) ===== Für zukünftige Versionen (v0.6+) ist die Einführung von Smart Pointers geplant, die eine automatisierte Referenzzählung (ARC) ermöglichen, um dispose in vielen Fällen optional zu machen.