En C++, la gestión de memoria se realiza mediante los operadores explícitos new y delete, que asignan y liberan memoria de forma dinámica. Sin embargo, con la gestión manual, es fácil provocar fugas de memoria o eliminaciones dobles.
Con la llegada del estándar C++11 se introdujeron punteros inteligentes, como std::unique_ptr, std::shared_ptr, std::weak_ptr. Ellos gestionan automáticamente el ciclo de vida de los objetos y garantizan la liberación de recursos cuando se sale del ámbito, incluso en caso de excepciones.
Ejemplo de comparación:
// Liberación manual de memoria Foo* ptr = new Foo(); // ... delete ptr; // Más seguro con puntero inteligente std::unique_ptr<Foo> ptr2 = std::make_unique<Foo>(); // delete no es necesario — todo lo hace unique_ptr
Los punteros inteligentes reducen el riesgo de fugas de memoria y hacen que el código sea más seguro y legible.
¿Qué sucede si se llama a delete dos veces para el mismo puntero?
Respuesta: Después de la primera llamada a delete, la memoria ya ha sido liberada. La llamada repetida resultará en comportamiento indefinido (undefined behavior). Ejemplo:
Foo* p = new Foo(); delete p; delete p; // ¡ERROR!
Para evitar esto, establece el puntero en nullptr después de liberarlo:
delete p; p = nullptr;
Historia
En un gran proyecto de C++, un desarrollador liberó manualmente la memoria dinámica a través de
delete, olvidando eliminar el puntero al salir de varias ramas de la función con excepciones. Esto llevó a fugas de memoria, detectadas solo durante pruebas de carga.
Historia
Al intentar compartir punteros crudos entre diferentes partes del código, se produjo una doble liberación de memoria: algunas partes del código hacían
delete, sin notificar a las demás. Resultado: segfault en producción, el análisis del core dump mostró la causa de inmediato.
Historia
Después de migrar un viejo proyecto a los nuevos estándares de C++, se dejó parte del código con punteros crudos, mientras que las nuevas clases ya trabajaban con punteros inteligentes. Se encontraron errores en la transferencia de la propiedad de los recursos: la memoria se liberaba "dos veces" — primero manualmente, luego automáticamente por los destructores de los punteros inteligentes.