Geschichte der Frage:
Der Stapelspeicher ist in allen gängigen Architekturen vorhanden. In der Sprache C werden automatische (lokale) Variablen auf dem Stack platziert, was im Vergleich zum dynamischen Heap eine hohe Geschwindigkeit der Speicherzuweisung und -freigabe bietet.
Problem:
Die Verwendung des Stacks ist in der Größe begrenzt, automatische Variablen werden automatisch zerstört, nachdem sie den Block verlassen haben, und ein Überlauf des Stacks (stack overflow) führt zu einem fehlerhaften Programmablauf oder Datenbeschädigungen.
Lösung:
Lokale Variablen, die innerhalb von Funktionen ohne speziellen Modifikator deklariert werden, werden auf dem Stack platziert. Dieser Bereich für automatische Speicherung wird beim Betreten der Funktion erstellt und beim Verlassen zerstört. Die Größe des Stacks ist begrenzt und kann nur durch Verlinkungs-/Systemoptionen geändert werden.
Beispielcode:
#include <stdio.h> void foo() { int arr[100]; // auf dem Stack platziert for (int i = 0; i < 100; ++i) arr[i] = i; printf("Erstes Element: %d\n", arr[0]); } // arr wird nach Verlassen von foo zerstört
Wesentliche Eigenschaften:
Kann man eine lokale Variable aus einer Funktion per Adresse zurückgeben?
Nein, weil die Variable nach dem Verlassen der Funktion zerstört wird und der resultierende "hängende Zeiger" zu undefiniertem Verhalten führt.
int* bad() { int x = 42; return &x; // Fehler: der zurückgegebene Zeiger zeigt auf einen freigegebenen Stack }
Ist es möglich, ein großes Array (z.B. 1 MB) auf dem Stack zu platzieren?
Für die meisten Systeme ist der Stack begrenzt (von Hunderten bis Tausenden von Kilobyte). Der Versuch, riesige Arrays auf dem Stack zu deklarieren, führt zu einem Stacküberlauf.
Was ist der Unterschied zwischen statischen und automatischen Variablen bei der Platzierung?
Statische Variablen (auch in Funktionen) werden im statischen Speicherbereich platziert, werden zwischen Aufrufen nicht gelöscht, während automatische Variablen auf dem Stack platziert werden und beim Verlassen des Blocks zerstört werden.
In einer Funktion zur Berechnung wurde ein Array von 8192*1024 double auf dem Stack zugewiesen. Das Programm erhielt bei der Ausführung in Linux einen SIGSEGV, obwohl es ohne Fehler kompiliert wurde.
Vorteile:
Nachteile:
Für die Arbeit mit großen Puffern wurde dynamische Speicherzuweisung über malloc/free verwendet. Auf dem Stack wurden nur kleine Arbeitsvariablen platziert.
Vorteile:
Nachteile: