Reputation: 45
for (int i = 0; i < 10; i++) {
thread *t = new thread(example_function);
t->join();
}
I am doing something similar in a coding project of mine and was wondering if since the threads get defined inside the loop they are destroyed after the loop ends (I know the pointer to the thread probably gets deleted but what about the thread itself?).
Upvotes: 1
Views: 952
Reputation: 726569
No, thread
objects created inside the for
loop are not destroyed, which means that they create memory leaks.
In order to make sure that the threads are destroyed you need to call delete
on them in one of several ways:
delete
at the end of the scope, ordelete
in a separate loop, orNote that since you are calling join
on each loop iteration your "concurrent" program is as good as a single-threaded one. Here is how to run your threads concurrently, and ensure thread deletions at the end:
std::vector<std::unique_ptr<std::thread>>> threads;
for (int i = 0; i < 10; i++) {
threads.push_back(std::make_unique<thread>(example_function));
}
for (int i = 0; i < 10; i++) {
threads[i]->join();
}
Once threads
vector goes out of scope, it deletes std::unique_ptr<thread>
objects inside it, which in turn calls delete
on the individual std::thread
objects.
Upvotes: 4
Reputation: 44248
I am doing something similar in a coding project of mine and was wondering if since the threads get defined inside the loop they are destroyed after the loop ends
Whole purpose of dynamic allocation using operator new
is to provide manual control over object lifetime. So no, until you explicitly call delete
or you use a smart pointer that does it for you under the hood your object would not be destroyed. Note, calling std::thread::join()
inside the loop effectively would make your program single threaded. More proper use would be:
std::vector<std::thread> threads;
while( threads.size() < 10 )
threads.emplace_back(example_function);
for( auto &thread : threads )
thread.join(); // join in a separate loop, let all threads to start
threads.clear(); // or let it go out of scope
Upvotes: 2
Reputation: 8589
No. The caller is responsible for ensuring objects allocated using new
are delete
d.
The code is of course pretty pointless because no meaningful concurrency occurs but to avoid a memory leak should be:
for (int i = 0; i < 10; i++) {
thread *t = new thread(example_function);
t->join();
delete t;
}
In any version of C++11 onwards it is recommended you use std::unique_ptr
in these cases:
The most recommended form is:
auto t{std::make_unique<std::thread>(example_function)};
Which is almost equivalent to:
std::unique_ptr<std::thread> t(new std::thread(example_function));
A std::unique_ptr
is an object that has operator overloading to behave a lot like a pointer with the difference of deleting the thing it points to (if anything) at the end of its life-time.
Upvotes: 0
Reputation: 8018
Here
thread *t = new thread(example_function);
you already loose the formerly allocated thread
instance and have a memory leak.
join()
doesn't free the allocated memory, but picks up the asynchonously ended function.
Upvotes: 0