0

When I use std::thread to call the function "void createMemoryLeak(const MustP3DPlugin& plugin)", the deconstructor of MustP3DPlugin is called as soon as the thread is finished. I didn't expect this and I was hoping someone could explain to me why this is happening.

#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() is called

    std::thread noMemoryLeakThread = std::thread(createNoMemoryLeak, this );
    noMemoryLeakThread.join();
    //but ~MustP3DPlugin() is not called here
}


MustP3DPlugin::~MustP3DPlugin() {
    MessageBox(nullptr, TEXT("~MustP3DPlugin()"), TEXT("debug text"), MB_OK);
}

void MustP3DPlugin::WaitOneSecond() const {
    Sleep(1000);
}
  • 3
    `std::thread memoryLeakThread = std::thread(createMemoryLeak, *this);` copy. "Whaaaaat? But I'm passing by reference!" you say? `thread` doesn't care. [It defaults to taking arguments by value](https://en.cppreference.com/w/cpp/thread/thread/thread#Notes) so that the parameters won't go out of scope before the thread is started (and other concurrency woes). Those copies are then passed by reference into `createMemoryLeak`. – user4581301 Nov 23 '21 at 17:56
  • 1
    Near duplicate: [Why does passing object reference arguments to thread function fails to compile?](https://stackoverflow.com/questions/8299545/why-does-passing-object-reference-arguments-to-thread-function-fails-to-compile) If it's enough, let me know and I'll formally close. – user4581301 Nov 23 '21 at 18:05
  • 2
    If you want to actually pass a reference into the thread function, use [`std::ref`](https://en.cppreference.com/w/cpp/utility/functional/ref) when you construct the thread object. – Pete Becker Nov 23 '21 at 18:13
  • 1
    If you want to clean up things via the destructor of `MustP3DPlugin`, you should mark copy constructor & copy assignment operator as deleted. Probably not really a memory leak btw: I expect all objects that were created to be destroyed... – fabian Nov 23 '21 at 18:28
  • Thank you guys! I didn't know std::thread doesn't care and does its own thing. Adding a copy constructor makes it clear what is going on. I should bring back my habit to always create a copy constructor. – Kay Goossen Nov 24 '21 at 08:49

0 Answers0