sadida sadida - 12 days ago 6
C++ Question

Static vs dynamic memory allocation for thread

I've written a sample program to show my problem - I don't understand why

firstVersion()
is working properly, and
secondVersion()
gives me error :
terminate called without an active exception Aborted
. Thanks for answers!
Here's the code :)


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

using namespace std;
const int threadCount = 100;
int N = 1;


void f() {
N++;
}

void firstVersion() {
thread * t[threadCount];
for(int i = 0; i < threadCount; i++) {
thread * ti = new thread{f};
t[i] = ti;
}
for(int i = 0; i < threadCount; i++) {
t[i]->join();
delete t[i];
}
}


void secondVersion() {
thread * t[threadCount];
for(int i = 0; i < threadCount; i++) {
thread ti{f};
t[i] = &ti;
}
for(int i = 0; i < threadCount; i++)
t[i]->join();
}

int main() {
//firstVersion();
secondVersion();
return 0;
}



Answer

The second version fails because the lifetime of thread ends at the end of your for loop before you call join().

void secondVersion() {
    thread * t[threadCount];
    for(int i = 0; i < threadCount; i++) {
        thread ti{f};        // local object of thread
        t[i] = &ti;
    }                        // the object dies without a join()

Your example can be simplified as:

void SomeFunc() {}

int main()
{
    std::thread* tp; 
    //{ 
        std::thread t{SomeFunc};
        tp= &t; 
    //}   // if the closing brace is present, object t calls destructor here!

    tp->join();

}

If you take a look into your STL you find the following code:

~thread()
{   
  if (joinable())
std::terminate();
}

That simply results in the call to the terminate.

So the example code make two mistakes:

1) Create a pointer to an object which dies before the pointer is used which is called dangling reference

2) Because thread object dies before join() was called, it simply calls terminate.