Menu
CoddyTech

Memoria dinámica (new/delete)

Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy. Lección 14 de 104.

Ahora que entiendes los punteros y las referencias, vamos a ponerlos en práctica con la asignación dinámica de memoria. Los operadores new y delete te permiten crear y destruir objetos en el montón durante la ejecución.

Usa new para asignar memoria y obtener un puntero a ella:

int* num = new int;        // Reserva memoria para un solo entero
*num = 42;                 // Asigna un valor mediante el puntero

Player* player = new Player("Hero");  // Reserva memoria para un objeto

Cada new debe tener un delete correspondiente para liberar la memoria:

delete num;      // Libera un único objeto
delete player;   // Llama al destructor y luego libera la memoria

Para los arreglos, usa new[] y delete[]:

int* scores = new int[5];    // Reserva memoria para un arreglo de 5 enteros
scores[0] = 100;

delete[] scores;             // Libera la memoria del arreglo: ¡fíjate en los corchetes!

Errores comunes que debes evitar:

// Fuga de memoria: se olvidó usar delete
int* ptr = new int(10);
ptr = new int(20);    // ¡Se perdió el acceso a la primera asignación de memoria!

// Puntero colgante: se usa después de delete
delete ptr;
*ptr = 5;             // ¡Comportamiento indefinido!

// Uso incorrecto de delete
int* arr = new int[10];
delete arr;           // ¡Incorrecto! Debería ser delete[]

Después de eliminar, asigna nullptr a los punteros para evitar reutilizarlos accidentalmente. La gestión manual de la memoria es propensa a errores, por eso el C++ moderno prefiere los punteros inteligentes, que exploraremos a continuación.

challenge icon

Desafío

Fácil

Vamos a crear un sistema sencillo de almacenamiento de mensajes que demuestre la asignación dinámica de memoria con new y delete.

Crearás dos archivos para organizar tu código:

  • MessageBox.h: Define una clase MessageBox que gestione dinámicamente un arreglo de mensajes. La clase debe tener:
    • Un puntero privado a un arreglo de cadenas asignado dinámicamente
    • Un entero privado que registre la cantidad actual de mensajes
    • Un entero privado que almacene la capacidad máxima
    • Un constructor que reciba una capacidad y asigne el arreglo usando new[]
    • Un destructor que libere correctamente la memoria usando delete[] e imprima "MessageBox destroyed"
    • Un método addMessage(string msg) que agregue un mensaje si hay espacio y devuelva true si tiene éxito o false si está lleno
    • Un método printAll() que imprima cada mensaje almacenado en su propia línea
  • main.cpp: Lee un valor de capacidad y una cantidad de mensajes desde la entrada. Después, lee esa cantidad de cadenas de mensajes. Crea un MessageBox en el montículo usando new, agrega todos los mensajes, llama a printAll() y luego elimina correctamente el MessageBox para liberar la memoria.

El formato de entrada será:

  • Primera línea: la capacidad (entero)
  • Segunda línea: la cantidad de mensajes que se agregarán (entero)
  • Líneas siguientes: un mensaje por línea

Recuerda: cada new necesita un delete correspondiente, y cada new[] necesita un delete[] correspondiente. Después de eliminar, es recomendable establecer los punteros en nullptr.

Incluye el archivo de encabezado en main.cpp usando #include "MessageBox.h".

Pruébalo tú mismo

#include <iostream>
#include <string>
#include "MessageBox.h"
using namespace std;

int main() {
    int capacity;
    int numMessages;
    
    // Lee la capacidad y el número de mensajes
    cin >> capacity;
    cin >> numMessages;
    cin.ignore(); // Elimina el salto de línea después del número
    
    // TODO: Crea un MessageBox en el montón usando new
    
    // TODO: Lee y añade todos los mensajes al MessageBox
    for (int i = 0; i < numMessages; i++) {
        string message;
        getline(cin, message);
        // Añade el mensaje al MessageBox
    }
    
    // TODO: Llama a printAll() para mostrar todos los mensajes
    
    // TODO: Elimina el MessageBox para liberar memoria
    // Recuerda establecer el puntero en nullptr después de eliminarlo
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C++ online