Comprobar fugas de memoria
En este paso, aprenderás cómo detectar y prevenir fugas de memoria en C++ utilizando Valgrind, una potente herramienta de depuración de memoria. Las fugas de memoria ocurren cuando la memoria asignada dinámicamente no se libera adecuadamente, lo que hace que tu programa consuma cantidades crecientes de memoria.
Primero, instala Valgrind en la terminal:
sudo apt update
sudo apt install -y valgrind
Crea un ejemplo de fuga de memoria en el WebIDE creando memory_leak.cpp
en el directorio ~/project
:
touch ~/project/memory_leak.cpp
Agrega el siguiente código a 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;
}
Compila el programa con símbolos de depuración:
g++ -g memory_leak.cpp -o memory_leak
Ejecuta Valgrind para detectar fugas de memoria:
valgrind --leak-check=full./memory_leak
Ejemplo de salida 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)
Como puedes ver, Valgrind detectó una fuga de memoria de 12 bytes en 3 bloques. El objeto Resource
creado en createMemoryLeak()
no se eliminó, lo que causó la fuga de memoria.
Para solucionar la fuga de memoria, modifica el código para eliminar adecuadamente los recursos:
void createMemoryLeak() {
// Properly delete the dynamically allocated resource
Resource* leak = new Resource(42);
delete leak; // Add this line to prevent memory leak
}
Compila y ejecuta el programa nuevamente con Valgrind para verificar que la fuga de memoria se haya solucionado:
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)
Puntos clave sobre las fugas de memoria:
- Siempre
delete
la memoria asignada dinámicamente
- Utiliza punteros inteligentes como
unique_ptr
y shared_ptr
- Utiliza Valgrind para detectar fugas de memoria
- Compila con la bandera
-g
para obtener mejor información de depuración