Zum Inhalt springen

Stapelüberlauf

aus Wikipedia, der freien Enzyklopädie

Vorlage:Hinweisbaustein Ein Stapelüberlauf (englisch stack overflow) findet statt, wenn der Aufrufstapel eines Programms die Größe des dafür vorgesehenen Speicherbereichs überschreitet.<ref>Robert Sheldon: What is stack overflow? Abgerufen am 27. August 2023 (Lua-Fehler in Modul:Multilingual, Zeile 153: attempt to index field 'data' (a nil value)).</ref>

Ein Stapelüberlauf verursacht üblicherweise den Absturz des Programms.

Ursachen

Rekursion

Da jeder Unterfunktionsaufruf durch einen Stack-Frame, der u. a. Funktionsargumente, lokale Variablen und die Rücksprungadresse enthält, repräsentiert wird, kann exzessive oder gar unendliche Rekursion den Aufrufstapel zum Überlaufen bringen.

Beispiel

Die folgende rekursive C-Funktion, die das i-te Element der Fibonacci-Folge zurückgibt, verursacht einen Stapelüberlauf, wenn i ausreichend groß ist.<syntaxhighlight lang="c"> long long fibonacci(int i) {

   if (i == 0) return 0;
   if (i == 1) return 1;
   return fibonacci(i-1) + fibonacci(i-2);

} </syntaxhighlight>

Große lokale Variablen

Da lokale Variablen üblicherweise im Aufrufstapel abgelegt werden, kann eine einzige übergroße lokale Variable einen Stapelüberlauf verursachen.

Beispiel

Das folgende C-Programm verwendet eine absurd große lokale Variable und kann somit einen Stapelüberlauf verursachen.<syntaxhighlight lang="c">

  1. include<stdio.h>

int main() {

   double daten[17179869184];
   printf("%f", daten[17179869183]);
   return 0;

} </syntaxhighlight>

Abhilfen

Rekursive Funktionen können immer in iterative umgewandelt werden, bei linear-rekursiven Funktionen (solche mit nur einem Rekursionsaufruf) und einigen weiteren einfachen Fällen geht das sogar formal.<ref>Peter Padawitz: Formale Methoden des Systemaufrufs. TU Dortmund, Dortmund 3. Februar 2021, S. 140 ff. (Volltext [PDF; abgerufen am 27. August 2023]).</ref> Einer iterativen Funktion, die nötigenfalls auch den Laufzeitstack imitiert (indem z. B. eine Stack-Datenstruktur „von Hand“ gefüllt wird), steht der gesamte Speicherbereich des Systems zur Verfügung, der üblicherweise mehrere Größenordnungen großzügiger ausfällt. Den Vorgang, bei dem eine rekursive Funktion in eine iterative überführt wird, nennt man Entrekursivierung. Nachteilig ist der oft komplexere Code und die dadurch eben nötige manuelle Speicherverwaltung, sofern nicht eine Laufzeitumgebung mit automatischer Speicherverwaltung eingesetzt wird.

Weblinks

Wiktionary: Stapelüberlauf – Bedeutungserklärungen, Wortherkunft, Synonyme, Übersetzungen

Einzelnachweise

<references />