9412 Stimmen

Was ist der Stack und der Heap und wo befinden sie sich?

  • Was sind der Stack und der Heap?
  • Wo befinden sie sich physisch im Speicher eines Computers?
  • In welchem Maße werden sie vom Betriebssystem oder der Laufzeitumgebung der Sprache kontrolliert?
  • Was ist ihr Geltungsbereich?
  • Was bestimmt ihre Größen?
  • Was macht einen schneller?

5 Stimmen

@mattshane Die Definitionen von Stack und Heap hängen überhaupt nicht von Wert- und Referenztypen ab. Mit anderen Worten, der Stack und Heap können vollständig definiert werden, auch wenn Wert- und Referenztypen niemals existiert hätten. Darüber hinaus ist der Stack nur ein Implementierungsdetail beim Verständnis von Wert- und Referenztypen. Laut Eric Lippert: Der Stack ist ein Implementierungsdetail, Teil Eins.

248 Stimmen

Eine wirklich gute Erklärung finden Sie hier Was ist der Unterschied zwischen einem Stapel und einem Heap?

19 Stimmen

Auch (wirklich) gut: codeproject.com/Articles/76153/… (der Stack-/Heap-Teil)

122voto

Ich denke, dass viele andere Leute Ihnen größtenteils richtige Antworten zu diesem Thema gegeben haben.

Allerdings wurde ein Detail übersehen, nämlich dass der "Heap" eigentlich wahrscheinlich als "Freispeicher" bezeichnet werden sollte. Der Grund für diese Unterscheidung ist, dass der ursprüngliche Freispeicher mit einer Datenstruktur namens "Binomialheap" implementiert wurde. Aus diesem Grund stammte in frühen Implementierungen von malloc()/free() eine Zuweisung aus einem Heap. Allerdings sind die meisten Freispeicher in der heutigen Zeit mit sehr aufwändigen Datenstrukturen implementiert, die keine Binomialheaps sind.

8 Stimmen

Eine weitere Kleinigkeit - die meisten Antworten suggerieren (leicht), dass die Verwendung eines "Stacks" von der C-Sprache erforderlich ist. Dies ist ein häufiges Missverständnis, obwohl es das (bei weitem) dominante Paradigma für die Implementierung von C99 6.2.4 automatische Speicherbereichsobjekte (Variablen) ist. Tatsächlich taucht das Wort "Stack" nicht einmal im C99-Sprachstandard auf: open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

0 Stimmen

[@Heath] Ich habe einen kleinen Kommentar zu deiner Antwort. Schau dir die akzeptierte Antwort auf diese Frage an. Es wird gesagt, dass der freie Speicher wahrscheinlich das Gleiche wie der Heap ist, aber nicht unbedingt.

97voto

Peter Punkte 1316

Sie können einige interessante Dinge mit dem Stack machen. Zum Beispiel haben Sie Funktionen wie alloca (vorausgesetzt, Sie können die zahlreichen Warnungen bezüglich seiner Verwendung überwinden), die eine Form von malloc ist, die speziell den Stack und nicht den Heap für den Speicher verwendet.

Abgesehen davon sind stackbasierte Speicherfehler einige der schlimmsten, die ich erlebt habe. Wenn Sie heapbasierten Speicher verwenden und die Grenzen Ihres allokierten Blocks überschreiten, besteht eine gute Chance, einen Segmentfehler auszulösen. (Nicht zu 100%: Ihr Block kann zufällig kontinuierlich mit einem anderen sein, den Sie zuvor allokiert haben.) Aber da Variablen, die auf dem Stack erstellt werden, immer miteinander kontinuierlich sind, kann das Schreiben außerhalb der Grenzen den Wert einer anderen Variable ändern. Ich habe gelernt, dass jedes Mal, wenn ich das Gefühl habe, dass mein Programm aufgehört hat, den Gesetzen der Logik zu gehorchen, wahrscheinlich ein Pufferüberlauf vorliegt.

0 Stimmen

Wie portabel ist alloca? Funktioniert es beispielsweise auf Windows? Ist es nur für Unix-ähnliche Betriebssysteme?

95voto

T.E.D. Punkte 42630

Einfach ausgedrückt, ist der Stack der Ort, an dem lokale Variablen erstellt werden. Außerdem werden jedes Mal, wenn Sie eine Unterfunktion aufrufen, der Programmzähler (Zeiger auf die nächste Maschinenanweisung), wichtige Register und manchmal die Parameter auf den Stack geschoben. Dann werden alle lokalen Variablen innerhalb der Unterfunktion auf den Stack geschoben (und von dort verwendet). Wenn die Unterfunktion endet, wird all das Zeug wieder vom Stack genommen. Die PC- und Registerdaten werden wieder an die Stelle zurückgesetzt, an der sie gestanden haben, als sie herausgeschoben wurden, damit Ihr Programm weiterlaufen kann.

Der Heap ist der Bereich des Speichers, in dem dynamische Speicherzuweisungen gemacht werden (explizite "new" oder "allocate" Aufrufe). Es handelt sich um eine spezielle Datenstruktur, die Blöcke von Speicher mit unterschiedlichen Größen und ihren Zuteilungsstatus verfolgen kann.

In "klassischen" Systemen war der RAM so angelegt, dass der Stackzeiger am unteren Ende des Speichers begann, der Heap-Zeiger am oberen Ende, und sie sich aufeinander zu bewegten. Wenn sie sich überlappen, haben Sie keinen RAM mehr zur Verfügung. Das funktioniert jedoch nicht bei modernen Multi-Thread-Betriebssystemen. Jeder Thread muss seinen eigenen Stack haben, und diese können dynamisch erstellt werden.

0 Stimmen

[@T.E.D.] Warum hast du gesagt "manchmal werden die Parameter auf den Stapel geschoben"? Was ich weiß, ist, dass sie immer sind. Könnten Sie bitte genauer darauf eingehen?

1 Stimmen

@OmarOthman - Ich sage das, weil es ausschließlich Sache des Autors Ihres Compilers / Interpreters ist, was passiert, wenn eine Unterprozedur aufgerufen wird. Das klassische Verhalten von Fortran besteht darin, überhaupt keinen Stack zu verwenden. Einige Sprachen unterstützen exotische Dinge wie das Durchreichen nach Namen, was effektiv eine textuelle Substitution ist.

87voto

devXen Punkte 2857

Von WikiAnwser.

Stack

Wenn eine Funktion oder eine Methode eine andere Funktion aufruft, die wiederum eine andere Funktion aufruft, usw., bleibt die Ausführung all dieser Funktionen ausgesetzt, bis die allerletzte Funktion ihren Wert zurückgibt.

Diese Kette von ausgesetzten Funktionsaufrufen wird als Stack bezeichnet, da Elemente im Stack (Funktionsaufrufe) voneinander abhängig sind.

Der Stack ist wichtig für die Betrachtung von Ausnahmebehandlung und Threadausführungen.

Heap

Der Heap ist einfach der Speicher, den Programme zum Speichern von Variablen verwenden. Elemente des Heaps (Variablen) haben keine Abhängigkeiten voneinander und können jederzeit zufällig abgerufen werden.

0 Stimmen

Ich mag die akzeptierte Antwort besser, da sie noch auf einer niedrigeren Ebene liegt. Das ist keine gute Sache, sondern eine schlechte Sache.

58voto

unknown Punkte 4441

Stapel

  • Sehr schneller Zugriff
  • Müssen Variablen nicht explizit de-allokieren
  • Speicher wird effizient vom CPU verwaltet, der Speicher wird nicht fragmentiert
  • Nur lokale Variablen
  • Limit für Stapelgröße (abhängig vom Betriebssystem)
  • Variablen können nicht vergrößert werden

Heap

  • Variablen können global zugegriffen werden
  • Kein Limit für Speichergröße
  • (Vergleichsweise) langsamer Zugriff
  • Keine garantiert effiziente Nutzung von Speicher, der Speicher kann mit der Zeit fragmentiert werden, da Blöcke von Speicher allokiert und dann freigegeben werden
  • Sie müssen den Speicher verwalten (Sie sind für die Allokation und Freigabe von Variablen verantwortlich)
  • Variablen können mit realloc() vergrößert werden

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X