Stack vs. Heap Speicher
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 12 von 104.
C++-Programme verwenden zwei Hauptspeicherbereiche: den Stack und den Heap. Zu verstehen, wo Ihre Objekte liegen, ist entscheidend für das Schreiben von effizientem, fehlerfreiem Code.
Der Stack ist ein schneller, automatischer Speicher. Variablen, die innerhalb von Funktionen deklariert werden, befinden sich hier und werden automatisch zerstört, wenn sie ihren Gültigkeitsbereich verlassen.
void example() {
int x = 10; // Stack-Allokierung
Player player; // Stack-Allokierung - wird automatisch zerstört
} // x und player werden hier zerstörtDer Heap ist ein größerer, aber langsamerer Speicher, den Sie manuell verwalten. Objekte auf dem Heap bleiben bestehen, bis Sie sie explizit löschen.
void example() {
Player* player = new Player(); // Heap-Allokation
// player existiert, bis er gelöscht wird
delete player; // Manuelle Bereinigung erforderlich
}Wesentliche Unterschiede:
| Stack | Heap |
|---|---|
| Schnelle Allokation | Langsamere Allokation |
| Begrenzte Größe | Große Kapazität |
| Automatische Bereinigung | Manuelle Bereinigung erforderlich |
| Objekte mit fester Größe | Objekte mit dynamischer Größe |
Verwenden Sie Stack-Allokation für kleine, kurzlebige Objekte. Verwenden Sie Heap-Allokation, wenn Objekte ihren Gültigkeitsbereich überdauern müssen oder wenn ihre Größe zur Laufzeit bestimmt wird.
Das Vergessen, Heap-Speicher zu löschen, verursacht Speicherlecks, eine häufige Fehlerquelle in C++-Programmen.
Aufgabe
EinfachLassen Sie uns den Unterschied zwischen Stack- und Heap-Speicher untersuchen, indem wir eine einfache Counter-Klasse erstellen, die verfolgt, wie Objekte erstellt und zerstört werden.
Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:
Counter.h: Definieren Sie eineCounter-Klasse mit einem privatenname-Attribut (String). Fügen Sie einen Konstruktor hinzu, der einen Namen entgegennimmt und"Creating: <name>"ausgibt, sowie einen Destruktor, der"Destroying: <name>"ausgibt. Fügen Sie einegetName()-Methode hinzu, um den Namen des Zählers zurückzugeben.main.cpp: Demonstrieren Sie sowohl Stack- als auch Heap-Allokation. Lesen Sie einen Namen von der Eingabe ein und führen Sie dann Folgendes aus:- Erstellen Sie einen auf dem Stack allokierten
Counterunter Verwendung dieses Namens - Erstellen Sie einen auf dem Heap allokierten
Countermit dem Namen"HeapCounter" - Geben Sie beide Zählernamen im Format
"Stack: <name>"und"Heap: <name>"aus - Löschen Sie den auf dem Heap allokierten Zähler, um ein Speicherleck zu vermeiden
- Erstellen Sie einen auf dem Stack allokierten
Beobachten Sie, wie die Konstruktor- und Destruktormeldungen in unterschiedlicher Reihenfolge erscheinen, je nachdem, wann Sie das jeweilige Objekt erstellen und löschen. Das Stack-Objekt wird automatisch zerstört, wenn main() endet, während das Heap-Objekt explizit gelöscht werden muss.
Binden Sie Ihre Header-Datei in main.cpp mit #include "Counter.h" ein.
Spickzettel
C++-Programme verwenden zwei Hauptspeicherbereiche: den Stack und den Heap.
Der Stack ist ein schneller, automatischer Speicher. Variablen, die innerhalb von Funktionen deklariert werden, befinden sich hier und werden automatisch zerstört, wenn sie ihren Gültigkeitsbereich verlassen:
void example() {
int x = 10; // Stack allocation
Player player; // Stack allocation - destroyed automatically
} // x and player are destroyed hereDer Heap ist ein größerer, aber langsamerer Speicher, den Sie manuell verwalten. Objekte auf dem Heap bleiben bestehen, bis Sie diese explizit löschen:
void example() {
Player* player = new Player(); // Heap allocation
// player exists until deleted
delete player; // Manual cleanup required
}Wesentliche Unterschiede:
| Stack | Heap |
|---|---|
| Schnelle Zuweisung | Langsamere Zuweisung |
| Begrenzte Größe | Große Kapazität |
| Automatische Bereinigung | Manuelle Bereinigung erforderlich |
| Objekte mit fester Größe | Objekte mit dynamischer Größe |
Verwenden Sie die Stack-Zuweisung für kleine, kurzlebige Objekte. Verwenden Sie die Heap-Zuweisung, wenn Objekte ihren Gültigkeitsbereich überdauern müssen oder wenn ihre Größe erst zur Laufzeit bestimmt wird. Das Vergessen des Löschens von Heap-Speicher führt zu Speicherlecks (Memory Leaks).
Probier es selbst
#include <iostream>
#include <string>
#include "Counter.h"
using namespace std;
int main() {
// Name von der Eingabe lesen
string inputName;
cin >> inputName;
// TODO: Erstelle einen Stack-allozierten Counter unter Verwendung von inputName
// TODO: Erstelle einen Heap-allozierten Counter mit dem Namen "HeapCounter"
// TODO: Gib den Namen des Stack-Counters im Format "Stack: <name>" aus
// TODO: Gib den Namen des Heap-Counters im Format "Heap: <name>" aus
// TODO: Lösche den Heap-allozierten Counter, um ein Speicherleck zu verhindern
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamensräume & GültigkeitsbereicheEinführung in OOP in C++Klassen vs. ObjekteDer 'this'-PointerMethoden (Elementfunktionen)Attribute (Datenelemente)Grundlagen zu Ctors & DtorsRückblick - Einfacher Taschenrechner4Klasseneigenschaften
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen & KlassenZusammenfassung - Bankkonto-Manager7Vererbung
Grundlagen der VererbungZugriffsstufen bei VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick - Mitarbeiter-Hierarchie2Speicherverwaltung
Stack vs. Heap SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Smart Pointers in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsspezifizierer in C++Zugriffsspezifizierer im DetailInformation HidingStruct vs. ClassVerschachtelte & innere KlassenRückblick - Studentenverwaltungssystem8Polymorphie
Kompilierzeit- vs. Laufzeit-PolymorphieFunktionsüberladungVirtuelle Funktionen – WiederholungRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIZusammenfassung – Formen-Rechner3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorVerschiebekonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktoren im DetailRule of Three / Five / ZeroZusammenfassung - String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladen der [] und () OperatorenTypumwandlungsoperatorenRückblick - Matrix-Klasse9Templates
FunktionstemplatesKlassentemplatesTemplate-SpezialisierungVariadische TemplatesSFINAE & Type Traits GrundlagenRückblick - Generische Container