Stack

Was ist der Stack? Der Stack ist eine spezielle Region im Speicher des Computers, die temporäre Variablen speichert, die von jeder Funktion (einschließlich der main() Funktion) erstellt wurden. Der Stack ist eine "LIFO" (last in, first out) Datenstruktur, die von der CPU sehr eng verwaltet und optimiert wird. Jedes Mal, wenn eine Funktion eine neue Variable deklariert, wird sie auf den Stack "geschoben". Jedes Mal, wenn eine Funktion beendet wird, werden alle von dieser Funktion auf den Stack geschobenen Variablen freigegeben (d.h. sie werden gelöscht). Sobald eine Stack-Variable freigegeben ist, wird dieser Speicherbereich für andere Stack-Variablen verfügbar.

Der Vorteil der Verwendung des Stacks zum Speichern von Variablen ist, dass der Speicher für Sie verwaltet wird. Sie müssen den Speicher nicht mehr von Hand zuweisen oder freigeben, wenn Sie ihn nicht mehr benötigen. Und weil die CPU den Stack-Speicher so effizient organisiert, ist das Lesen und Schreiben von Stack-Variablen sehr schnell.

Ein Schlüssel zum Verständnis des Stacks ist die Vorstellung, dass beim Beenden einer Funktion alle ihre Variablen vom Stapel verschwinden (und somit für immer verloren gehen). Daher sind Stackvariablen von lokaler Natur. Dies hängt mit einem Konzept zusammen, das früher als Variablenbereich oder lokale vs. globale Variablen bekannt war. Ein häufiger Fehler in der C-Programmierung ist der Versuch, auf eine Variable zuzugreifen, die auf dem Stack innerhalb einer Funktion erstellt wurde, von einer Stelle in Ihrem Programm außerhalb dieser Funktion (d.h. nachdem diese Funktion beendet wurde).

Eine weitere Besonderheit des Stacks ist, dass es ein Limit (variiert mit dem Betriebssystem) für die Größe der Variablen gibt, die auf dem Stack gespeichert werden können. Dies gilt nicht für die auf dem Heap zugewiesenen Variablen. 



Heap

Der Heap ist ein Bereich des Arbeitsspeichers Ihres Computers, der nicht automatisch für Sie verwaltet wird und nicht so eng von der CPU verwaltet wird. Es ist ein freischwebender Bereich des Speichers (und ist größer). Um Speicher auf dem Heap zuzuweisen, müssen Sie malloc() oder calloc() verwenden, die eingebaute C-Funktionen sind. Sobald Sie Speicher auf dem Heap zugewiesen haben, sind Sie dafür verantwortlich, dass Sie free() verwenden, um diesen Speicher wieder freizugeben, sobald Sie ihn nicht mehr benötigen. Wenn Sie dies nicht tun, hat Ihr Programm ein so genanntes Speicherleck. Das heißt, der Speicher auf dem Heap wird weiterhin beiseite gelegt (und steht für andere Prozesse nicht zur Verfügung). 

Im Gegensatz zum Stack hat der Heap keine Größenbeschränkungen für die variable Größe (abgesehen von den offensichtlichen physischen Einschränkungen Ihres Computers). Heap-Speicher ist etwas langsamer zu lesen und zu beschreiben, da man mit Zeigern auf den Speicher auf dem Heap zugreifen muss. 

Im Gegensatz zum Stack sind Variablen, die auf dem Heap erstellt wurden, von jeder Funktion und überall in Ihrem Programm zugänglich. Heap-Variablen sind im Wesentlichen global angelegt.



Vergleich zwischen Stack und Heap


Stack Heap
- sehr schneller Zugriff - langsamerer Zugriff
- Variablen müssen nicht explizit gelöscht werden - Variablen müssen explizit gelöscht werden
- der Speicher wird effizient von der CPU verwaltet - der Speicher wird langsamer vom Betriebssystem verwaltet
- eine Fragmentierung des Speichers ist nicht möglich - der Speicher ist mit hoher Wahrscheinlichkeit fragmentiert
- es können nur lokale Variablen abgelegt werden - Variablen sind global zugreifbar
- die Größe des Stacks ist beschränkt - die maximale Größe ist nur durch den physisch verfügbaren Speicher gegenzt
- Variaben können nicht in ihrer Größe geändert werden - Variablen können in ihrer Größe geändert werden (realloc)


Wann verwenden wir was?

Wann sollten Sie den Heap und wann den Stack verwenden? Wenn Sie einen großen Speicherblock (z.B. ein großes Array oder eine große Struktur) allokieren müssen und diese Variable über einen langen Zeitraum (wie eine globale Variable) behalten müssen, dann sollten Sie sie auf dem Heap allokieren. Wenn Sie es mit relativ kleinen Variablen zu tun haben, die nur so lange bestehen müssen, wie die Funktion, die sie verwendet, noch lebt, dann sollten Sie den Stack verwenden. Er ist einfacher und schneller. Wenn Sie Variablen wie Arrays und Strukturen benötigen, die die Größe dynamisch ändern können (z.B. Arrays, die bei Bedarf wachsen oder schrumpfen können), dann müssen Sie sie wahrscheinlich auf dem Heap zuweisen und dynamische Speicherzuweisungsfunktionen wie malloc(), calloc(), realloc() und free() verwenden, um diesen Speicher "von Hand" zu verwalten. 



Quelle: https://www.gribblelab.org/CBootCamp/7_Memory_Stack_vs_Heap.html





Zuletzt geändert: Donnerstag, 17. Mai 2018, 15:31