Vérifier les fuites de mémoire
Dans cette étape, vous allez apprendre à détecter et à prévenir les fuites de mémoire en C++ en utilisant Valgrind, un outil puissant de débogage mémoire. Les fuites de mémoire se produisent lorsque la mémoire allouée dynamiquement n'est pas correctement libérée, ce qui fait que votre programme consomme de plus en plus de mémoire.
Tout d'abord, installez Valgrind dans le terminal :
sudo apt update
sudo apt install -y valgrind
Créez un exemple de fuite de mémoire dans le WebIDE en créant le fichier memory_leak.cpp
dans le répertoire ~/project
:
touch ~/project/memory_leak.cpp
Ajoutez le code suivant à memory_leak.cpp
:
#include <iostream>
class Resource {
public:
Resource(int value) : data(value) {
std::cout << "Resource created: " << data << std::endl;
}
~Resource() {
std::cout << "Resource destroyed: " << data << std::endl;
}
private:
int data;
};
void createMemoryLeak() {
// This creates a memory leak because the resource is not deleted
Resource* leak = new Resource(42);
// Missing: delete leak;
}
int main() {
// Simulate multiple memory leaks
for (int i = 0; i < 3; ++i) {
createMemoryLeak();
}
return 0;
}
Compilez le programme avec des symboles de débogage :
g++ -g memory_leak.cpp -o memory_leak
Exécutez Valgrind pour détecter les fuites de mémoire :
valgrind --leak-check=full./memory_leak
Exemple de sortie de 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==
Resource created: 42
Resource created: 42
Resource created: 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)
Comme vous pouvez le voir, Valgrind a détecté une fuite de mémoire de 12 octets répartis sur 3 blocs. L'objet Resource
créé dans createMemoryLeak()
n'a pas été supprimé, ce qui a entraîné la fuite de mémoire.
Pour corriger la fuite de mémoire, modifiez le code pour supprimer correctement les ressources :
void createMemoryLeak() {
// Properly delete the dynamically allocated resource
Resource* leak = new Resource(42);
delete leak; // Add this line to prevent memory leak
}
Compilez et exécutez le programme à nouveau avec Valgrind pour vérifier que la fuite de mémoire est corrigée :
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==
Resource created: 42
Resource destroyed: 42
Resource created: 42
Resource destroyed: 42
Resource created: 42
Resource destroyed: 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)
Points clés concernant les fuites de mémoire :
- Toujours utiliser
delete
pour libérer la mémoire allouée dynamiquement
- Utiliser des pointeurs intelligents comme
unique_ptr
et shared_ptr
- Utiliser Valgrind pour détecter les fuites de mémoire
- Compiler avec le flag
-g
pour obtenir de meilleures informations de débogage