Ich möchte DFS auf einem 100 x 100-Array ausführen. (Angenommen, Elemente des Arrays stellen Diagrammknoten dar.) Unter der Annahme des schlimmsten Falls kann die Tiefe rekursiver Funktionsaufrufe bis zu 10000 betragen, wobei jeder Aufruf bis zu 20 Bytes benötigt. Ist es also machbar, dass die Möglichkeit eines Stapelüberlaufs besteht?
Was ist die maximale Größe des Stapels in C / C ++?
Bitte geben Sie für gcc für beide
1) cygwin unter Windows
2) Unix an
Was sind die allgemeinen Grenzen?
Antworten:
In Visual Studio beträgt die Standardstapelgröße meiner Meinung nach 1 MB. Bei einer Rekursionstiefe von 10.000 kann jeder Stapelrahmen höchstens ~ 100 Byte betragen, was für einen DFS-Algorithmus ausreichend sein sollte.
Bei den meisten Compilern, einschließlich Visual Studio, können Sie die Stapelgröße angeben. Bei einigen (allen?) Linux-Varianten ist die Stapelgröße nicht Teil der ausführbaren Datei, sondern eine Umgebungsvariable im Betriebssystem. Sie können dann die Stapelgröße mit überprüfen
ulimit -s
und sie beispielsweise mit auf einen neuen Wert setzenulimit -s 16384
.Hier ist ein Link mit Standardstapelgrößen für gcc.
DFS ohne Rekursion:
quelle
Stapel für Fäden sind oft kleiner. Sie können die Standardeinstellung zur Verbindungszeit oder auch zur Laufzeit ändern. Als Referenz sind einige Standardeinstellungen:
quelle
Plattformabhängig, Toolchain-abhängig, ulimit-abhängig, parameterabhängig ... Es ist überhaupt nicht spezifiziert, und es gibt viele statische und dynamische Eigenschaften, die es beeinflussen können.
quelle
Ja, es besteht die Möglichkeit eines Stapelüberlaufs. Der C- und C ++ - Standard schreibt keine Dinge wie die Stapeltiefe vor, diese sind im Allgemeinen ein Umweltproblem.
In den meisten anständigen Entwicklungsumgebungen und / oder Betriebssystemen können Sie die Stapelgröße eines Prozesses entweder zum Zeitpunkt der Verknüpfung oder zum Laden anpassen.
Sie sollten angeben, welches Betriebssystem und welche Entwicklungsumgebung Sie für eine gezieltere Unterstützung verwenden.
Unter Ubuntu Karmic Koala ist der Standardwert für gcc beispielsweise 2M reserviert und 4K festgeschrieben. Dies kann jedoch geändert werden, wenn Sie das Programm verknüpfen. Verwenden Sie dazu die
--stack
Optionld
.quelle
Bei der Arbeit ging mir gerade der Stapel aus, es war eine Datenbank und es wurden einige Threads ausgeführt. Im Grunde hatte der vorherige Entwickler ein großes Array auf den Stapel geworfen, und der Stapel war sowieso niedrig. Die Software wurde mit Microsoft Visual Studio 2015 kompiliert.
Obwohl der Thread keinen Stapel mehr hatte, schlug er stillschweigend fehl und fuhr fort. Der Stapel lief nur über, wenn er auf den Inhalt der Daten auf dem Stapel zugreifen wollte.
Der beste Rat, den ich geben kann, ist, keine Arrays auf dem Stapel zu deklarieren - insbesondere in komplexen Anwendungen und insbesondere in Threads -, sondern Heap zu verwenden. Dafür ist es da;)
Denken Sie auch daran, dass es beim Deklarieren des Stapels möglicherweise nicht sofort fehlschlägt, sondern nur beim Zugriff. Ich vermute, dass der Compiler den Stapel unter Windows "optimistisch" deklariert, dh er geht davon aus, dass der Stapel deklariert wurde und eine ausreichende Größe hat, bis er verwendet wird, und stellt dann fest, dass der Stapel nicht vorhanden ist.
Unterschiedliche Betriebssysteme haben möglicherweise unterschiedliche Richtlinien für die Stapeldeklaration. Bitte hinterlassen Sie einen Kommentar, wenn Sie diese Richtlinien kennen.
quelle
Ich bin mir nicht sicher, was Sie unter einer Tiefensuche in einem rechteckigen Array verstehen, aber ich gehe davon aus, dass Sie wissen, was Sie tun.
Wenn das Stapellimit ein Problem darstellt, sollten Sie in der Lage sein, Ihre rekursive Lösung in eine iterative Lösung umzuwandeln, die Zwischenwerte auf einen Stapel überträgt, der vom Heap zugewiesen wird.
quelle