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.

Llamada de desconstructor inesperada al finalizar un std::thread.

Cuando uso std::thread para llamar a la función “void createMemoryLeak(const MustP3DPlugin& plugin)”, el destructor de MustP3DPlugin es llamado tan pronto como el hilo termina. No esperaba esto y esperaba que alguien pudiera explicarme por qué está sucediendo esto.

#include <Windows.h>
#include <thread>

class MustP3DPlugin {
public:
MustP3DPlugin();
~MustP3DPlugin();

void WaitOneSecond() const;

};

int main() {
MustP3DPlugin plugin = MustP3DPlugin();
}

void createNoMemoryLeak(const MustP3DPlugin* plugin) {
plugin->WaitOneSecond();
}

void createMemoryLeak(const MustP3DPlugin& plugin) {
plugin.WaitOneSecond();
}

MustP3DPlugin::MustP3DPlugin() {
std::thread memoryLeakThread = std::thread(createMemoryLeak, *this);
memoryLeakThread.join();
//~MustP3DPlugin() es llamado

std::thread noMemoryLeakThread = std::thread(createNoMemoryLeak, this );
noMemoryLeakThread.join();
//pero ~MustP3DPlugin() no es llamado aquí

}

MustP3DPlugin::~MustP3DPlugin() {
MessageBox(nullptr, TEXT(” ~MustP3DPlugin()”), TEXT(“texto de depuración”), MB_OK);
}

void MustP3DPlugin::WaitOneSecond() const {
Sleep(1000);
}

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Cuando se pasa el argumento “*this” al constructor std::thread en createMemoryLeak, se crea una copia de MustP3DPlugin en el hilo que se está ejecutando de forma asíncrona. Dado que el argumento pasado es una referencia (&) al objeto MustP3DPlugin, esta copia se crea a través de un constructor de copia. Cuando se destruye la copia, se llama al destructor de MustP3DPlugin para esta copia, no para el objeto original que se creó en main(). Por lo tanto, “~MustP3DPlugin()” se llama tan pronto como el hilo finaliza la ejecución.

    Si desea evitar este comportamiento y hacer que el destructor se llame después de que se ejecute “noMemoryLeakThread”, puede pasar un puntero al constructor de hilo y dejar que el hilo reciba la dirección original que se está almacenando en la variable plugin. De esta manera, no se llamará ningún destructor mientras se ejecute el hilo.

    std::thread memoryLeakThread = std::thread(createMemoryLeak, &plugin);
    
    void createMemoryLeak(MustP3DPlugin* plugin) {
            plugin->WaitOneSecond();
        }
    

Comments are closed.