Stack vs. Heap: Unterschiede im Speicher erklärt
Ein laufendes Programm nutzt zwei Hauptbereiche des Speichers für seine Daten. Der Stack enthält die Aufruf-Frames von Funktionen: lokale Variablen, Argumente und Rücksprungadressen. Er wird automatisch verwaltet und ist sehr schnell, aber klein und an die Lebensdauer des jeweiligen Funktionsaufrufs gebunden. Der Heap enthält Speicher, den das Programm explizit anfordert, etwa mit malloc oder new, und der bis zur Freigabe bestehen bleibt. Der Heap ist flexibel und groß, aber langsamer, und hier entstehen Speicherlecks und Fragmentierung.
| Aspekt | Stack | Heap |
|---|---|---|
| Verwendet für | Funktionsaufruf-Frames: lokale Variablen, Argumente, Rücksprungadressen | Dynamisch allokierte Daten, die eine Funktion überdauern müssen oder deren Größe vorab nicht bekannt ist |
| Allokation | Automatisch: Der Stackpointer bewegt sich bei jedem Aufruf und Rücksprung | Explizit: malloc und free, new und delete, oder ein Garbage Collector |
| Geschwindigkeit | Sehr schnell: nur ein Zeiger wird angepasst | Langsamer: Der Allokator muss einen freien Block finden und Buch führen |
| Lebensdauer | Bis die Funktion zurückkehrt | Bis der Speicher freigegeben wird (oder der Garbage Collector ihn einsammelt) |
| Größe | Begrenzt (typischerweise einige Megabyte pro Thread) | Nur durch den verfügbaren Speicher begrenzt |
| Aufbau | Wächst meist von hohen Adressen nach unten | Wächst meist von niedrigeren Adressen nach oben, sodass beide aufeinander zuwachsen |
| Fragmentierung | Keine | Möglich: Wiederholtes Allokieren und Freigeben kann unbrauchbare Lücken hinterlassen |
| Threads | Jeder Thread hat seinen eigenen, privaten Stack | Von allen Threads geteilt, daher muss der Allokator threadsicher sein |
| Typische Fehler | Stack Overflow durch tiefe Rekursion oder große lokale Arrays | Speicherlecks, Use-after-free, Double-free und Speichermangel |
Die Zahlenangaben sind typische Größenordnungen und variieren je nach Prozessgeneration und Produkt.