Prüfen auf Speicherlecks
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_ptr
und shared_ptr
.
- Verwenden Sie Valgrind, um Speicherlecks zu erkennen.
- Kompilieren Sie mit der
-g
-Option für bessere Debugging-Informationen.