Menu
Coddy logo textTech

Dynamischer Speicher (new/delete)

Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 14 von 104.

Nachdem Sie nun Zeiger und Referenzen verstehen, lassen Sie uns diese bei der dynamischen Speicherallokation einsetzen. Die Operatoren new und delete ermöglichen es Ihnen, Objekte zur Laufzeit auf dem Heap zu erstellen und zu zerstören.

Verwenden Sie new, um Speicher zuzuweisen und einen Zeiger darauf zurückzuerhalten:

int* num = new int;        // Einzelnen Integer allozieren
*num = 42;                 // Wert über Zeiger zuweisen

Player* player = new Player("Hero");  // Objekt allozieren

Jedes new muss ein passendes delete haben, um den Speicher freizugeben:

delete num;      // Einzelnes Objekt freigeben
delete player;   // Ruft den Destruktor auf und gibt dann den Speicher frei

Verwenden Sie für Arrays new[] und delete[]:

int* scores = new int[5];    // Array von 5 Integern reservieren
scores[0] = 100;

delete[] scores;             // Array freigeben - beachten Sie die Klammern!

Häufige Fehler, die vermieden werden sollten:

// Speicherleck - Löschen vergessen
int* ptr = new int(10);
ptr = new int(20);    // Zugriff auf die erste Zuweisung verloren!

// Dangling Pointer - Verwendung nach dem Löschen
delete ptr;
*ptr = 5;             // Undefiniertes Verhalten!

// Falsches delete
int* arr = new int[10];
delete arr;           // Falsch! Sollte delete[] sein

Nach dem Löschen sollten Zeiger auf nullptr gesetzt werden, um eine versehentliche Wiederverwendung zu vermeiden. Die manuelle Speicherverwaltung ist fehleranfällig, weshalb modernes C++ Smart Pointer bevorzugt, die wir als Nächstes untersuchen werden.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein einfaches Nachrichtenspeichersystem bauen, das die dynamische Speicherallokation mit new und delete demonstriert.

Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:

  • MessageBox.h: Definieren Sie eine MessageBox-Klasse, die ein Array von Nachrichten dynamisch verwaltet. Die Klasse sollte Folgendes haben:
    • Einen privaten Pointer auf ein dynamisch allokiertes Array von Strings
    • Einen privaten Integer, der die aktuelle Anzahl der Nachrichten verfolgt
    • Einen privaten Integer, der die maximale Kapazität speichert
    • Einen Konstruktor, der eine Kapazität entgegennimmt und das Array mit new[] allokiert
    • Einen Destruktor, der den Speicher ordnungsgemäß mit delete[] freigibt und "MessageBox destroyed" ausgibt
    • Eine addMessage(string msg)-Methode, die eine Nachricht hinzufügt, wenn Platz vorhanden ist, und bei Erfolg true oder bei Vollbelegung false zurückgibt
    • Eine printAll()-Methode, die jede gespeicherte Nachricht in einer eigenen Zeile ausgibt
  • main.cpp: Lesen Sie einen Kapazitätswert und eine Anzahl von Nachrichten von der Eingabe ein. Lesen Sie dann entsprechend viele Nachrichtenzeichenfolgen ein. Erstellen Sie eine MessageBox auf dem Heap mit new, fügen Sie alle Nachrichten hinzu, rufen Sie printAll() auf und löschen Sie die MessageBox anschließend ordnungsgemäß, um Speicher freizugeben.

Das Eingabeformat ist wie folgt:

  • Erste Zeile: die Kapazität (Integer)
  • Zweite Zeile: die Anzahl der hinzuzufügenden Nachrichten (Integer)
  • Folgende Zeilen: eine Nachricht pro Zeile

Denken Sie daran: Jedes new benötigt ein passendes delete, und jedes new[] benötigt ein passendes delete[]. Nach dem Löschen ist es gute Praxis, Pointer auf nullptr zu setzen.

Binden Sie Ihre Header-Datei in main.cpp mit #include "MessageBox.h" ein.

Spickzettel

Verwenden Sie new, um Speicher dynamisch auf dem Heap zu reservieren und einen Zeiger darauf zu erhalten:

int* num = new int;        // Einzelnen Integer reservieren
*num = 42;                 // Wert über Zeiger zuweisen

Player* player = new Player("Hero");  // Objekt reservieren

Jedem new muss ein passendes delete entsprechen, um den Speicher freizugeben:

delete num;      // Einzelnes Objekt freigeben
delete player;   // Ruft den Destruktor auf und gibt dann den Speicher frei

Verwenden Sie für Arrays new[] und delete[]:

int* scores = new int[5];    // Array von 5 Integern reservieren
scores[0] = 100;

delete[] scores;             // Array freigeben - beachten Sie die Klammern!

Häufige Fehler, die vermieden werden sollten:

// Speicherleck - delete vergessen
int* ptr = new int(10);
ptr = new int(20);    // Zugriff auf die erste Reservierung verloren!

// Dangling Pointer - Verwendung nach delete
delete ptr;
*ptr = 5;             // Undefiniertes Verhalten!

// Falsches delete
int* arr = new int[10];
delete arr;           // Falsch! Sollte delete[] sein

Setzen Sie Zeiger nach dem Löschen auf nullptr, um eine versehentliche Wiederverwendung zu vermeiden.

Probier es selbst

#include <iostream>
#include <string>
#include "MessageBox.h"
using namespace std;

int main() {
    int capacity;
    int numMessages;
    
    // Kapazität und Anzahl der Nachrichten einlesen
    cin >> capacity;
    cin >> numMessages;
    cin.ignore(); // Den Zeilenumbruch nach der Zahl entfernen
    
    // TODO: Eine MessageBox auf dem Heap mit new erstellen
    
    // TODO: Alle Nachrichten einlesen und zur MessageBox hinzufügen
    for (int i = 0; i < numMessages; i++) {
        string message;
        getline(cin, message);
        // Nachricht zur MessageBox hinzufügen
    }
    
    // TODO: printAll() aufrufen, um alle Nachrichten anzuzeigen
    
    // TODO: Die MessageBox löschen, um Speicher freizugeben
    // Daran denken, den Pointer nach dem Löschen auf nullptr zu setzen
    
    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung