Introducción: por qué C++ es difícil pero interesante
C++ es uno de los lenguajes de programación más potentes y eficientes. Pero un gran poder conlleva una gran responsabilidad. Los desarrolladores principiantes a menudo se enfrentan a errores que pueden provocar fallos del programa, fugas de memoria y comportamiento indefinido. En este artículo, analizaremos los 10 errores más comunes de los principiantes en C++ — de la A a la Z. Aprenderás a reconocerlos, corregirlos y, lo más importante, a no cometerlos en el futuro. El material será útil tanto para estudiantes como para aquellos que recién comienzan su camino en la programación de sistemas.
1. Ignorar el comportamiento indefinido (UB)
Uno de los errores más engañosos es el comportamiento indefinido (Undefined Behavior, UB). El compilador no emitirá una advertencia, el programa puede funcionar "aparentemente bien", pero al cambiar las optimizaciones o la plataforma, todo se derrumbará.
Ejemplo: salirse de los límites del array
int arr[5] = {1, 2, 3, 4, 5};arr[5] = 42; // UB: salirse de los límitesstd::cout << arr[10]; // UB: lectura de basuraCómo evitarlo: Utiliza siempre std::array o std::vector con verificación mediante .at(), así como los contenedores de STL. Nunca confíes en la "suerte" — el UB puede manifestarse en el momento más inoportuno.
2. Fugas de memoria y punteros sin procesar
En C++ no hay recolector de basura. Cada new debe tener su correspondiente delete. Los principiantes a menudo olvidan liberar la memoria, especialmente cuando hay excepciones.
Ejemplo de fuga
void leak() { int* p = new int(100); // olvidamos delete p; // al salir de la función, la memoria se pierde}Solución: Usa punteros inteligentes: std::unique_ptr para propiedad exclusiva y std::shared_ptr para propiedad compartida. Ellos liberarán la memoria automáticamente al salir del ámbito.
void no_leak() { auto p = std::make_unique<int>(100); // delete se llama automáticamente}3. Uso incorrecto de referencias y punteros
La confusión entre referencias (&) y punteros (*) es un problema común.
- Referencia — es un alias. No puede ser
nullptry no se reasigna. - Puntero puede ser nulo y puede apuntar a diferentes objetos.
Error típico: devolver una referencia a un objeto local
int& bad_ref() { int x = 10; return x; // x se destruirá al salir}// uso: int& r = bad_ref(); // referencia colganteRegla: Nunca devuelvas referencias o punteros a variables locales. Solo a datos cuya vida útil esté garantizada (por ejemplo, argumentos pasados por referencia o variables estáticas).
4. Descuidar RAII (Resource Acquisition Is Initialization)
RAII es un idioma clave de C++. El recurso (memoria, archivo, mutex) se adquiere en el constructor y se libera en el destructor. Los principiantes a menudo escriben gestión manual, lo que provoca fugas cuando hay excepciones.
Ejemplo malo
void handle_file() { FILE* f = fopen("data.txt", "r"); // ... trabajar con el archivo ... if (some_error) { return; // ¡olvidamos fclose! } fclose(f);}Ejemplo bueno con RAII
void handle_file_safe() { std::ifstream f("data.txt"); if (!f) return; // ... trabajar ... // el archivo se cerrará automáticamente al salir del scope}Conclusión: Siempre envuelve los recursos en envoltorios RAII. Para archivos — std::fstream, para memoria — punteros inteligentes, para mutex — std::lock_guard.
5. Ignorar const y constexpr
Muchos principiantes no usan