15

I have some code that dynamically allocates a new std::thread from the C++11 <thread> header, like this:

std::thread *th = new thread( /* my args */);

Some time later, I call join:

th->join();

Since I dynamically allocated the thread, do I also need to call delete th; to free the memory? If I do, do I still need to call join() first?

bobroxsox
  • 902
  • 2
  • 10
  • 26
  • 2
    I think you do. But why not use shared_ptr since you are using C++11? – Yuchen May 07 '15 at 01:17
  • I learned C++ before C++11 came out and am still learning about all the new stuff. Didn't think to use shared_ptr :) – bobroxsox May 07 '15 at 01:37
  • 4
    or better, use `std::unique_ptr`, unless you really need shared ownership. Heaving a unique owner also makes it clear who is responsible for the joining – Fabio Fracassi May 07 '15 at 08:53

2 Answers2

21

To avoid memory leaks, you need to both: join a running thread, and make sure it is destructed/deleted (let it go out of scope for stack-allocated std::threads or explicitly call delete for std::thread*).

See thread::~thread in cppreference:

A thread object does not have an associated thread (and is safe to destroy) after:

  • it was default-constructed
  • it was moved from
  • join() has been called
  • detach() has been called

A non-joined thread, therefore, cannot be safely destructed.

A join()ed std::thread will still occupy some memory. Therefore you need to make sure it is properly deallocated if it is on the heap.

EyasSH
  • 3,679
  • 22
  • 36
6

Yes you have to call join before destroying the thread object. If the destructor for a std::thread object that is joinable (i.e. if joinable returns true) is called, it will call std::terminate. Therefore, you have to call join before destroying the thread, whether by calling delete (for threads on the heap) or by it being destroyed normally.

To prevent a memory leak you have to call delete, as with any other heap allocated variable.

See here for more information on std::thread.

bobroxsox
  • 902
  • 2
  • 10
  • 26
phantom
  • 3,292
  • 13
  • 21