Einführung
In diesem Lab werden Sie lernen, wie Sie dynamische Speicherzuweisung in C++ handhaben. Sie beginnen damit, Speicher mit dem new-Operator zuzuweisen und geben ihn anschließend mit dem delete-Operator wieder frei. Sie werden auch die Erstellung dynamischer Arrays untersuchen, intelligente Zeiger wie shared_ptr und unique_ptr verwenden und auf Speicherlecks prüfen. Diese Fähigkeiten sind für eine effektive Speicherverwaltung in der C++-Programmierung unerlässlich.
Das Lab behandelt die folgenden Schlüsselpunkte: Zuweisen von Speicher mit dem new-Operator, Freigeben von Speicher mit dem delete-Operator, Erstellen dynamischer Arrays mit new[], Löschen von Arrays mit delete[], Implementieren des shared_ptr-Smartpointers, Verwenden von unique_ptr für exklusiven Besitz, Prüfen auf Speicherlecks und Behandeln von Fehlern bei der Speicherzuweisung.
Speicher mit dem new-Operator zuweisen
In diesem Schritt lernen Sie, wie Sie den new-Operator in C++ verwenden, um Speicher dynamisch zur Laufzeit zuzuweisen. Die dynamische Speicherzuweisung ermöglicht es Ihnen, Variablen und Arrays zu erstellen, deren Größe während der Programmausführung bestimmt wird. Dies bietet mehr Flexibilität im Vergleich zur statischen Speicherzuweisung.
Öffnen Sie die WebIDE und erstellen Sie eine neue Datei namens dynamic_memory.cpp im Verzeichnis ~/project:
touch ~/project/dynamic_memory.cpp
Fügen Sie den folgenden Code in die Datei dynamic_memory.cpp ein:
#include <iostream>
int main() {
// Dynamisch einen Integer mit new zuweisen
int* dynamicInteger = new int;
// Einen Wert dem dynamisch zugewiesenen Integer zuweisen
*dynamicInteger = 42;
// Den Wert des dynamisch zugewiesenen Integers ausgeben
std::cout << "Dynamisch zugewiesener Integer-Wert: " << *dynamicInteger << std::endl;
// Die Speicheradresse des dynamisch zugewiesenen Integers ausgeben
std::cout << "Speicheradresse: " << dynamicInteger << std::endl;
return 0;
}
Lassen Sie uns die wichtigsten Konzepte analysieren:
int* dynamicInteger = new int;:- Der
new-Operator weist Speicher für einen Integer zu. - Gibt einen Zeiger auf den zugewiesenen Speicher zurück.
- Erstellt die Variable auf dem Heap, nicht auf dem Stack.
- Der
*dynamicInteger = 42;:- Verwendet den Dereferenzierungsoperator
*, um einen Wert zuzuweisen. - Speichert den Wert 42 im dynamisch zugewiesenen Speicher.
- Verwendet den Dereferenzierungsoperator
Kompilieren und führen Sie das Programm aus:
g++ dynamic_memory.cpp -o dynamic_memory
./dynamic_memory
Beispielausgabe:
Dynamisch zugewiesener Integer-Wert: 42
Speicheradresse: 0x55f4e8a042a0
Wichtige Punkte zum new-Operator:
- Weist Speicher dynamisch zur Laufzeit zu.
- Gibt einen Zeiger auf den zugewiesenen Speicher zurück.
- Der Speicher wird auf dem Heap zugewiesen.
- Die Größe kann zur Laufzeit bestimmt werden.
- Ermöglicht eine flexiblere Speicherverwaltung.
Hinweis: In den nächsten Schritten lernen Sie, wie Sie diesen dynamisch zugewiesenen Speicher richtig freigeben, um Speicherlecks zu vermeiden.
Speicher mit dem delete-Operator freigeben
In diesem Schritt lernen Sie, wie Sie den delete-Operator verwenden, um dynamisch zugewiesenen Speicher in C++ richtig freizugeben. Wenn Sie den Speicher nicht freigeben, kann dies zu Speicherlecks führen, die Leistungsprobleme in Ihrem Programm verursachen können.
Öffnen Sie die WebIDE und erstellen Sie eine neue Datei namens memory_release.cpp im Verzeichnis ~/project:
touch ~/project/memory_release.cpp
Fügen Sie den folgenden Code in die Datei memory_release.cpp ein:
#include <iostream>
int main() {
// Dynamisch einen Integer zuweisen
int* dynamicInteger = new int;
// Einen Wert dem dynamisch zugewiesenen Integer zuweisen
*dynamicInteger = 42;
// Den Wert vor der Freigabe des Speichers ausgeben
std::cout << "Wert vor Freigabe: " << *dynamicInteger << std::endl;
// Den dynamisch zugewiesenen Speicher mit delete freigeben
delete dynamicInteger;
// Den Zeiger nach der Löschung auf nullptr setzen
dynamicInteger = nullptr;
// Demonstrieren Sie die sichere Verwendung des Zeigers
if (dynamicInteger == nullptr) {
std::cout << "Speicher wurde erfolgreich freigegeben" << std::endl;
}
return 0;
}
Wichtige Punkte zum delete-Operator:
delete dynamicInteger;:- Gibt den zuvor mit
newzugewiesenen Speicher frei. - Vermeidet Speicherlecks.
- Gibt den Speicher an das System zurück.
- Gibt den zuvor mit
dynamicInteger = nullptr;:- Setzt den Zeiger nach der Löschung auf
nullptr. - Hilft, versehentliche Verwendung von freigegebenem Speicher zu vermeiden.
- Bietet eine zusätzliche Sicherheitsüberprüfung.
- Setzt den Zeiger nach der Löschung auf
Kompilieren und führen Sie das Programm aus:
g++ memory_release.cpp -o memory_release
./memory_release
Beispielausgabe:
Wert vor Freigabe: 42
Speicher wurde erfolgreich freigegeben
Wichtige Regeln für die Speicherverwaltung:
- Verwenden Sie immer
deletefür Speicher, der mitnewzugewiesen wurde. - Setzen Sie Zeiger nach der Löschung auf
nullptr. - Verwenden Sie einen Zeiger nie nach seiner Löschung.
- Jeder
new-Aufruf sollte einen entsprechendendelete-Aufruf haben.
Dynamische Arrays mit new[] erstellen
In diesem Schritt lernen Sie, wie Sie dynamische Arrays mit dem new[]-Operator in C++ erstellen. Dynamische Arrays ermöglichen es Ihnen, zur Laufzeit Speicher für mehrere Elemente zuzuweisen und bieten damit mehr Flexibilität als statische Arrays.
Öffnen Sie die WebIDE und erstellen Sie eine neue Datei namens dynamic_array.cpp im Verzeichnis ~/project:
touch ~/project/dynamic_array.cpp
Fügen Sie den folgenden Code in die Datei dynamic_array.cpp ein:
#include <iostream>
int main() {
// Deklarieren Sie die Größe des dynamischen Arrays
int arraySize = 5;
// Erstellen Sie ein dynamisches Integer-Array mit new[]
int* dynamicArray = new int[arraySize];
// Initialisieren Sie die Array-Elemente
for (int i = 0; i < arraySize; ++i) {
dynamicArray[i] = i * 10;
}
// Geben Sie die Array-Elemente aus
std::cout << "Inhalt des dynamischen Arrays:" << std::endl;
for (int i = 0; i < arraySize; ++i) {
std::cout << "Element " << i << ": " << dynamicArray[i] << std::endl;
}
return 0;
}
Wichtige Punkte zu dynamischen Arrays:
int* dynamicArray = new int[arraySize];:- Weist Speicher für ein Array von Integern zu.
arraySizebestimmt die Anzahl der Elemente.- Der Speicher wird auf dem Heap zugewiesen.
- Die Größe kann zur Laufzeit bestimmt werden.
Array-Initialisierung und -Zugriff:
- Verwenden Sie die Standard-Array-Indizierung
dynamicArray[i]. - Kann wie ein normales Array manipuliert werden.
- Ermöglicht eine dynamische Größenbestimmung basierend auf Laufzeitbedingungen.
- Verwenden Sie die Standard-Array-Indizierung
Kompilieren und führen Sie das Programm aus:
g++ dynamic_array.cpp -o dynamic_array
./dynamic_array
Beispielausgabe:
Inhalt des dynamischen Arrays:
Element 0: 0
Element 1: 10
Element 2: 20
Element 3: 30
Element 4: 40
Wichtige Überlegungen:
- Dynamische Arrays bieten Flexibilität bei der Speicherzuweisung.
- Die Größe kann zur Laufzeit bestimmt werden.
- Denken Sie daran,
new[]für die Zuweisung unddelete[]für die Freigabe zu verwenden. - Passen Sie immer die Zuweisungs- und Freigabemethoden aneinander an.
Arrays mit delete[] löschen
In diesem Schritt lernen Sie, wie Sie den für dynamische Arrays zugewiesenen Speicher richtig mit dem delete[]-Operator freigeben. Eine korrekte Speicherverwaltung ist entscheidend, um Speicherlecks zu vermeiden und eine effiziente Ressourcennutzung zu gewährleisten.
Öffnen Sie die WebIDE und erstellen Sie eine neue Datei namens delete_array.cpp im Verzeichnis ~/project:
touch ~/project/delete_array.cpp
Fügen Sie den folgenden Code in die Datei delete_array.cpp ein:
#include <iostream>
int main() {
// Deklarieren Sie die Größe des dynamischen Arrays
int arraySize = 5;
// Erstellen Sie ein dynamisches Integer-Array mit new[]
int* dynamicArray = new int[arraySize];
// Initialisieren Sie die Array-Elemente
for (int i = 0; i < arraySize; ++i) {
dynamicArray[i] = i * 10;
}
// Geben Sie die Array-Elemente vor der Löschung aus
std::cout << "Inhalt des Arrays vor der Löschung:" << std::endl;
for (int i = 0; i < arraySize; ++i) {
std::cout << "Element " << i << ": " << dynamicArray[i] << std::endl;
}
// Geben Sie das dynamisch zugewiesene Array mit delete[] frei
delete[] dynamicArray;
// Setzen Sie den Zeiger nach der Löschung auf nullptr
dynamicArray = nullptr;
// Demonstrieren Sie die sichere Verwendung des Zeigers
if (dynamicArray == nullptr) {
std::cout << "Dynamisches Array wurde erfolgreich gelöscht" << std::endl;
}
return 0;
}
Wichtige Punkte zum Löschen dynamischer Arrays:
delete[] dynamicArray;:- Gibt den Speicher für das gesamte Array richtig frei.
- Muss
delete[]für Arrays verwenden, die mitnew[]zugewiesen wurden. - Vermeidet Speicherlecks.
- Ruft den Destruktor für jedes Array-Element auf.
dynamicArray = nullptr;:- Setzt den Zeiger nach der Löschung auf
nullptr. - Vermeidet versehentlichen Zugriff auf freigegebenen Speicher.
- Bietet eine zusätzliche Sicherheitsüberprüfung.
- Setzt den Zeiger nach der Löschung auf
Kompilieren und führen Sie das Programm aus:
g++ delete_array.cpp -o delete_array
./delete_array
Beispielausgabe:
Inhalt des Arrays vor der Löschung:
Element 0: 0
Element 1: 10
Element 2: 20
Element 3: 30
Element 4: 40
Dynamisches Array wurde erfolgreich gelöscht
Wichtige Regeln für die Speicherverwaltung:
- Verwenden Sie immer
delete[]für Arrays, die mitnew[]zugewiesen wurden. - Vermischen Sie nie
deleteunddelete[]. - Setzen Sie Zeiger nach der Löschung auf
nullptr. - Jeder
new[]-Aufruf sollte einen entsprechendendelete[]-Aufruf haben.
Implementieren Sie den Smart Pointer shared_ptr
In diesem Schritt lernen Sie über shared_ptr, einen Smart Pointer aus der C++ Standardbibliothek, der automatische Speicherverwaltung und Referenzzählung bietet. Smart Pointer helfen, Speicherlecks zu vermeiden und vereinfachen die Speicherverwaltung.
Öffnen Sie die WebIDE und erstellen Sie eine neue Datei namens shared_pointer.cpp im Verzeichnis ~/project:
touch ~/project/shared_pointer.cpp
Fügen Sie den folgenden Code in die Datei shared_pointer.cpp ein:
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass(int value) : data(value) {
std::cout << "Konstruktor aufgerufen. Wert: " << data << std::endl;
}
~MyClass() {
std::cout << "Destruktor aufgerufen. Wert: " << data << std::endl;
}
int getData() const { return data; }
private:
int data;
};
int main() {
// Erstellen Sie einen shared_ptr für MyClass
std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>(42);
// Erstellen Sie einen weiteren shared_ptr, der auf dasselbe Objekt zeigt
std::shared_ptr<MyClass> ptr2 = ptr1;
// Geben Sie die Referenzzählung aus
std::cout << "Referenzzählung: " << ptr1.use_count() << std::endl;
// Greifen Sie auf das Objekt über den shared_ptr zu
std::cout << "Daten von ptr1: " << ptr1->getData() << std::endl;
std::cout << "Daten von ptr2: " << ptr2->getData() << std::endl;
// Die Pointer geben den Speicher automatisch frei, wenn sie aus dem Gültigkeitsbereich gehen
return 0;
}
Wichtige Punkte zu shared_ptr:
std::make_shared<MyClass>(42):- Erstellt einen Shared Pointer mit dynamischer Speicherzuweisung.
- Initialisiert das Objekt mit einem Konstruktor-Argument.
- Ist effizienter als die separate Erstellung von
newundshared_ptr.
ptr1.use_count():- Gibt die Anzahl der
shared_ptr-Instanzen zurück, die auf dasselbe Objekt zeigen. - Hilft, die Referenzzählung des Objekts zu verfolgen.
- Gibt die Anzahl der
Automatische Speicherverwaltung:
- Der Speicher wird automatisch freigegeben, wenn kein
shared_ptrmehr auf das Objekt verweist. - Vermeidet Fehler bei der manuellen Speicherverwaltung.
- Der Speicher wird automatisch freigegeben, wenn kein
Kompilieren und führen Sie das Programm aus:
g++ -std=c++11 shared_pointer.cpp -o shared_pointer
./shared_pointer
Beispielausgabe:
Konstruktor aufgerufen. Wert: 42
Referenzzählung: 2
Daten von ptr1: 42
Daten von ptr2: 42
Destruktor aufgerufen. Wert: 42
Wichtige Eigenschaften von shared_ptr:
- Automatische Speicherverwaltung
- Referenzzählung
- Vermeidung von Speicherlecks
- Thread-sichere Referenzzählung
Verwenden Sie unique_ptr für exklusiven Besitz
In diesem Schritt lernen Sie über unique_ptr, einen Smart Pointer, der exklusive Besitzrechte an dynamisch zugewiesenen Ressourcen gewährt. Im Gegensatz zu shared_ptr stellt unique_ptr sicher, dass nur ein einziger Pointer zur gleichen Zeit die Ressource besitzen kann.
Öffnen Sie die WebIDE und erstellen Sie eine neue Datei namens unique_pointer.cpp im Verzeichnis ~/project:
touch ~/project/unique_pointer.cpp
Fügen Sie den folgenden Code in die Datei unique_pointer.cpp ein:
#include <iostream>
#include <memory>
class Resource {
public:
Resource(int value) : data(value) {
std::cout << "Ressource erstellt. Wert: " << data << std::endl;
}
~Resource() {
std::cout << "Ressource zerstört. Wert: " << data << std::endl;
}
int getData() const { return data; }
private:
int data;
};
void processResource(std::unique_ptr<Resource> resource) {
std::cout << "Verarbeitung der Ressource mit Wert: " << resource->getData() << std::endl;
// Die Ressource wird automatisch gelöscht, wenn die Funktion endet
}
int main() {
// Erstellen Sie einen unique_ptr
std::unique_ptr<Resource> ptr1 = std::make_unique<Resource>(42);
// Geben Sie die Ressourcendaten aus
std::cout << "Ressourcenwert: " << ptr1->getData() << std::endl;
// Übertragen Sie die Besitzrechte mit std::move
std::unique_ptr<Resource> ptr2 = std::move(ptr1);
// ptr1 ist jetzt nullptr
if (ptr1 == nullptr) {
std::cout << "ptr1 ist nach Übertragung der Besitzrechte null" << std::endl;
}
// Übergeben Sie den unique_ptr an eine Funktion (Besitzrechte werden übertragen)
processResource(std::move(ptr2));
return 0;
}
Wichtige Punkte zu unique_ptr:
std::make_unique<Resource>(42):- Erstellt einen Unique Pointer mit dynamischer Speicherzuweisung.
- Stellt exklusive Besitzrechte an der Ressource sicher.
std::move(ptr1):- Übertragt die Besitzrechte an der Ressource.
- Der ursprüngliche Pointer wird
nullptr. - Verhindert, dass mehrere Pointer dieselbe Ressource besitzen.
Automatische Speicherverwaltung:
- Die Ressource wird automatisch gelöscht, wenn der
unique_ptraus dem Gültigkeitsbereich geht. - Keine manuelle Speicherverwaltung erforderlich.
- Die Ressource wird automatisch gelöscht, wenn der
Kompilieren und führen Sie das Programm aus:
g++ -std=c++14 unique_pointer.cpp -o unique_pointer
./unique_pointer
Beispielausgabe:
Ressource erstellt. Wert: 42
Ressourcenwert: 42
ptr1 ist nach Übertragung der Besitzrechte null
Verarbeitung der Ressource mit Wert: 42
Ressource zerstört. Wert: 42
Wichtige Eigenschaften von unique_ptr:
- Exklusive Besitzrechte
- Automatische Speicherverwaltung
- Kann nicht kopiert, nur verschoben werden
- Verhindert Ressourcenlecks
Auf Speicherlecks prüfen
In diesem Schritt lernen Sie, wie Sie Speicherlecks in C++ mit Valgrind, einem leistungsstarken Speicher-Debugging-Tool, erkennen und vermeiden können. Speicherlecks treten auf, wenn dynamisch zugewiesener Speicher nicht richtig freigegeben wird, was dazu führt, dass Ihr Programm immer mehr Speicher verbraucht.
Zuerst installieren Sie Valgrind im Terminal:
sudo apt update
sudo apt install -y valgrind
Erstellen Sie ein Beispiel für ein Speicherleck in der WebIDE, indem Sie memory_leak.cpp im Verzeichnis ~/project erstellen:
touch ~/project/memory_leak.cpp
Fügen Sie den folgenden Code in die Datei memory_leak.cpp ein:
#include <iostream>
class Resource {
public:
Resource(int value) : data(value) {
std::cout << "Ressource erstellt: " << data << std::endl;
}
~Resource() {
std::cout << "Ressource zerstört: " << data << std::endl;
}
private:
int data;
};
void createMemoryLeak() {
// Dies erzeugt ein Speicherleck, da die Ressource nicht gelöscht wird
Resource* leak = new Resource(42);
// Fehlt: delete leak;
}
int main() {
// Simulieren Sie mehrere Speicherlecks
for (int i = 0; i < 3; ++i) {
createMemoryLeak();
}
return 0;
}
Kompilieren Sie das Programm mit Debugging-Symbolen:
g++ -g memory_leak.cpp -o memory_leak
Führen Sie Valgrind aus, um Speicherlecks zu erkennen:
valgrind --leak-check=full./memory_leak
Beispielausgabe von Valgrind:
==1988== Memcheck, a memory error detector
==1988== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1988== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1988== Command:./memory_leak
==1988==
Ressource erstellt: 42
Ressource erstellt: 42
Ressource erstellt: 42
==1988==
==1988== HEAP SUMMARY:
==1988== in use at exit: 12 bytes in 3 blocks
==1988== total heap usage: 5 allocs, 2 frees, 73,740 bytes allocated
==1988==
==1988== 12 bytes in 3 blocks are definitely lost in loss record 1 of 1
==1988== at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1988== by 0x109241: createMemoryLeak() (memory_leak.cpp:19)
==1988== by 0x109299: main (memory_leak.cpp:26)
==1988==
==1988== LEAK SUMMARY:
==1988== definitely lost: 12 bytes in 3 blocks
==1988== indirectly lost: 0 bytes in 0 blocks
==1988== possibly lost: 0 bytes in 0 blocks
==1988== still reachable: 0 bytes in 0 blocks
==1988== suppressed: 0 bytes in 0 blocks
==1988==
==1988== For lists of detected and suppressed errors, rerun with: -s
==1988== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Wie Sie sehen können, hat Valgrind ein Speicherleck von 12 Bytes in 3 Blöcken erkannt. Das in createMemoryLeak() erstellte Resource-Objekt wurde nicht gelöscht, was das Speicherleck verursacht.
Um das Speicherleck zu beheben, ändern Sie den Code so, dass die Ressourcen richtig gelöscht werden:
void createMemoryLeak() {
// Löschen Sie die dynamisch zugewiesene Ressource richtig
Resource* leak = new Resource(42);
delete leak; // Fügen Sie diese Zeile hinzu, um Speicherlecks zu vermeiden
}
Kompilieren und führen Sie das Programm erneut mit Valgrind aus, um zu überprüfen, ob das Speicherleck behoben ist:
g++ -g memory_leak.cpp -o memory_leak
valgrind --leak-check=full./memory_leak
==2347== Memcheck, a memory error detector
==2347== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2347== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==2347== Command:./memory_leak
==2347==
Ressource erstellt: 42
Ressource zerstört: 42
Ressource erstellt: 42
Ressource zerstört: 42
Ressource erstellt: 42
Ressource zerstört: 42
==2347==
==2347== HEAP SUMMARY:
==2347== in use at exit: 0 bytes in 0 blocks
==2347== total heap usage: 5 allocs, 5 frees, 73,740 bytes allocated
==2347==
==2347== All heap blocks were freed -- no leaks are possible
==2347==
==2347== For lists of detected and suppressed errors, rerun with: -s
==2347== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Wichtige Punkte zu Speicherlecks:
- Löschen Sie immer dynamisch zugewiesenen Speicher mit
delete. - Verwenden Sie Smart Pointer wie
unique_ptrundshared_ptr. - Verwenden Sie Valgrind, um Speicherlecks zu erkennen.
- Kompilieren Sie mit der
-g-Option für bessere Debugging-Informationen.
Behandeln Sie Speicherzuweisungsfehler
In diesem Schritt lernen Sie, wie Sie Speicherzuweisungsfehler in C++ behandeln können. Wenn die dynamische Speicherzuweisung fehlschlägt, wirft der new-Operator eine std::bad_alloc-Ausnahme, die Sie fangen und elegant behandeln können.
Öffnen Sie die WebIDE und erstellen Sie eine neue Datei namens memory_allocation.cpp im Verzeichnis ~/project:
touch ~/project/memory_allocation.cpp
Fügen Sie den folgenden Code in die Datei memory_allocation.cpp ein:
#include <iostream>
#include <new>
#include <limits>
void demonstrateMemoryAllocation() {
try {
// Versuchen Sie, eine große Menge an Speicher zuzuweisen
const size_t largeSize = 1000000000000; // 1 Billion Integer
int* largeArray = new int[largeSize];
// Diese Zeile wird nicht erreicht, wenn die Zuweisung fehlschlägt
std::cout << "Speicherzuweisung erfolgreich" << std::endl;
// Geben Sie den zugewiesenen Speicher frei
delete[] largeArray;
}
catch (const std::bad_alloc& e) {
// Behandeln Sie den Speicherzuweisungsfehler
std::cerr << "Speicherzuweisung fehlgeschlagen: " << e.what() << std::endl;
}
}
void safeMemoryAllocation() {
// Verwenden Sie std::nothrow, um das Werfen von Ausnahmen zu verhindern
int* safeArray = new(std::nothrow) int[1000000];
if (safeArray == nullptr) {
std::cerr << "Speicherzuweisung stumm fehlgeschlagen" << std::endl;
return;
}
// Verwenden Sie den zugewiesenen Speicher
std::cout << "Sichere Speicherzuweisung erfolgreich" << std::endl;
// Geben Sie den zugewiesenen Speicher frei
delete[] safeArray;
}
int main() {
std::cout << "Demonstration des Umgangs mit Speicherzuweisungsfehlern:" << std::endl;
// Methode 1: Verwendung von Ausnahmebehandlung
demonstrateMemoryAllocation();
// Methode 2: Verwendung von std::nothrow
safeMemoryAllocation();
return 0;
}
Wichtige Punkte zum Umgang mit Speicherzuweisungsfehlern:
Ausnahmebehandlung mit
std::bad_alloc:- Ein
try-catch-Block fängt Speicherzuweisungsausnahmen auf. - Liefert detaillierte Fehlerinformationen.
- Verhindert Abstürze des Programms.
- Ein
Speicherzuweisung mit
std::nothrow:- Verhindert das Werfen von Ausnahmen.
- Gibt
nullptrbei einer fehlgeschlagenen Zuweisung zurück. - Ermöglicht die stumme Behandlung von Fehlern.
Kompilieren und führen Sie das Programm aus:
g++ memory_allocation.cpp -o memory_allocation
./memory_allocation
Beispielausgabe:
Demonstration des Umgangs mit Speicherzuweisungsfehlern:
Speicherzuweisung fehlgeschlagen: std::bad_alloc
Sichere Speicherzuweisung erfolgreich
Wichtige Strategien für die Speicherzuweisung:
- Prüfen Sie immer auf Zuweisungsfehler.
- Verwenden Sie Ausnahmebehandlung oder
std::nothrow. - Implementieren Sie Fallback-Mechanismen.
- Vermeiden Sie die Zuweisung extrem großer Speicherblöcke.
Zusammenfassung
In diesem Lab lernen Sie, wie Sie die dynamische Speicherzuweisung in C++ handhaben können. Zunächst lernen Sie, den new-Operator zu verwenden, um Speicher zur Laufzeit dynamisch zuzuweisen. Dies ermöglicht eine flexiblere Speicherverwaltung im Vergleich zur statischen Zuweisung. Anschließend lernen Sie, wie Sie diesen dynamisch zugewiesenen Speicher richtig mit dem delete-Operator freigeben, um Speicherlecks zu vermeiden. Darüber hinaus werden Sie die Erstellung dynamischer Arrays mit new[] und deren Löschung mit delete[] untersuchen. Das Lab behandelt auch die Verwendung von Smart Pointern wie shared_ptr und unique_ptr, um die Speicherverwaltung zu vereinfachen und häufige Fallstricke zu vermeiden. Schließlich lernen Sie Techniken kennen, um Speicherzuweisungsfehler zu erkennen und zu behandeln.



