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é las variables miembro son modificables incluso después de que un objeto sea destruido?

Si shared_ptr se destruye, ¿qué sucede con “this” si se captura en una lambda para ejecutarse en un hilo? ¿No debería haber lanzado una excepción en el caso a continuación, ya que el objeto Test se destruyó antes de que el hilo pudiera finalizar su ejecución?

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;
using namespace std::this_thread; // sleep_for, sleep_until
using namespace std::chrono; // nanoseconds, system_clock, seconds

class Test 
{
    private:
    int testInt = 0;

    public:
    std::thread TestMethod()
    {
        auto functor = 
        [this]() -> void 
        {
            sleep_until(system_clock::now() + seconds(1));
            ++testInt; cout<<><endl; };="" std::thread="" t1(functor);="" testint="6;" return="" t1;="" }="" ~test()="" {="" cout<<"destruido\n";="" testint="2;" }="" };="" int="" main()="" {="" cout<<"crear="" test\n";="" auto="" testptr=""></endl;><test>();
    auto t = testPtr->TestMethod();
    testPtr = nullptr;
    cout<<"Destruir Test\n";
    t.join();

    return 0;
}

La salida es:

Crear Test
Destruido
Destruir Test
3

¿Cómo puede la lambda acceder a testInt de un objeto destruido?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Cuando se destruye un shared_ptr, se decrementa el contador de referencias del objeto y, si el contador alcanza 0, se destruye el objeto. En el caso de la lambda capturada por TestMethod, el shared_ptr a Test es destruido después de que la lambda es creada pero antes de que se ejecute en el nuevo hilo. Sin embargo, el shared_ptr no destruye inmediatamente el objeto Test. En cambio, espera hasta que todas las copias del shared_ptr sean destruidas y el contador de referencias alcance 0. La lambda captura el puntero this de Test, que todavía apunta al objeto Test incluso después de que su shared_ptr sea destruido.

    Por lo tanto, cuando la lambda se ejecuta en el nuevo hilo, aún tiene acceso al objeto Test y a su miembro de variable testInt. En este caso, el objeto Test se destruye después de que la lambda ha terminado de ejecutarse, por lo que no hay ningún problema. Sin embargo, si el objeto Test fuera destruido antes de que la lambda terminara de ejecutarse, podría provocar un comportamiento indefinido y potencialmente una violación de acceso a la memoria.

    En este ejemplo específico, el objeto Test se destruye después de que la lambda completa su ejecución en el nuevo hilo, por lo que no se produce ninguna excepción. La salida muestra que la lambda pudo acceder a la variable miembro testInt del objeto Test destruido y aumentarla a 3 antes de que la función principal se uniera al hilo.

Comments are closed.