es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué los compiladores no llaman automáticamente al destructor cuando se declara un objeto mediante el operador new?

#include <iostream>

using namespace std;

class b {
public:
    int *a;

    b(int val) {
        a = new int;
        *a = val;
    }

    ~b() {
        cout << "destructor" << endl;
        delete a;
    }
};

int main() {
    b *obj = new b(1);
    cout << "end" << endl;
    delete obj;
    return 0;
}

Resultado esperado:

destructor
end

Resultado recibido:

end

En el código anterior, el compilador no llama al destructor cuando se crea un objeto utilizando el operador new, pero en el caso de un objeto normal, el destructor se llama correctamente. ¿Cuál es la razón detrás de esto?

#include <iostream>

using namespace std;

class b {
public:
    int *a;

    b(int val) {
        a = new int;
        *a = val;
    }

    ~b() {
        cout << "destructor" << endl;
        delete a;
    }
};

int main() {
    b *obj = new b(1);
    cout << "end" << endl;
    delete obj;
    return 0;
}

En el código anterior, se debe usar el operador new para crear un objeto de la clase b y luego se debe llamar al destructor manualmente usando delete para liberar la memoria asignada. En otras palabras, el motivo por el que el destructor no se llama automáticamente cuando se usa new es porque new crea un objeto en el heap y no en la pila. Es responsabilidad del programador liberar la memoria llamando explícitamente a delete.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La razón detrás de esto es que cuando usas el operador “new” para crear un objeto, el objeto se crea en el montón y se devuelve un puntero a él. Por lo tanto, cuando el programa termina, la memoria asignada para el objeto no se libera automáticamente, a diferencia de cuando se crea un objeto en la pila.

    Para que se llame al destructor de un objeto creado mediante “new”, debes eliminar manualmente el objeto usando el operador “delete”. En este código en particular, se llama al operador “delete” dentro del destructor de la clase b. Sin embargo, olvidaste asignar memoria para “a” antes de intentar asignarle un valor, por lo que el programa provoca un comportamiento indefinido. Para solucionar esto, debes asignar memoria para “a” utilizando el operador “new” dentro del constructor de la clase b, de la siguiente manera:

    b (int val) {
        a = new int;
        *a = val;
    }
    

    Esto asignará memoria para “a” en el montón, lo que te permitirá asignarle un valor de manera segura y luego eliminarlo dentro del destructor.

Comments are closed.