I have the following code written using C++17 standard:
std::mutex mutex{};
struct Test {
~Test() {
{
std::lock_guard lock{mutex};
std::cout << "~Test() = " << a << std::endl;
}
delete a;
}
int *a;
};
thread_local Test test{};
void Foo(int i) {
test.a = new int{i};
std::lock_guard lock{mutex};
std::cout << "Thread: " << std::this_thread::get_id() << " value: " << test.a
<< std::endl;
}
int main() {
std::vector<std::thread> threads;
threads.reserve(7);
for (std::size_t i{1}; i < 8; ++i) {
threads.emplace_back(Foo, i);
}
Foo(0);
for (auto &thread : threads) {
thread.join();
}
threads.clear();
return 0;
}
I just create some threads and initialize thread local variable test by allocating new memory. Of course I should not forget to free the memory allocated before; and I do so in a destructor of the thread local object (Test::~Test()). But I gain what is not expected: when the destructor of any thread start executing it doesn't have the same value of pointer that was allocated in Foo(), therefore, in the end, I get an error.
Possible output of this program (debug):
Thread: 4 value: 0x14ca4b81ae0
Thread: 2 value: 0x14ca4b84f80
~Test() thread: 4 value: 0x211bbc59c792f
Thread: 3 value: 0x14ca4b847a0
Signal: SIGTRAP (Trace/breakpoint trap)
Signal: ? (Unknown signal)
Possible output of this program (non-debug):
Thread: 2 value: 0x224eb8926c0
Thread: 3 value: 0x224eb892820
~Test() thread: 2 value: 0x224eb8926c0
Thread: 1 value: 0x224eba77670
~Test() thread: 3 value: 0x224eb892820
Thread: 6 value: 0x224eba77650
~Test() thread: 6 value: 0x224eba77650
Thread: 5 value: 0x224eba776a0
~Test() thread: 5 value: 0x224eba776a0
Thread: 4 value: 0x224eba77680
~Test() thread: 4 value: 0x224eba77680
Thread: 7 value: 0x224eba77700
~Test() thread: 7 value: 0x224eba77700
Thread: 8 value: 0x224eba77690
~Test() thread: 8 value: 0x224eba77690
~Test() thread: 1 value: 0x224eba77670
Process finished with exit code 0
What do I do wrong with the thread local variable?
UPDATE
The problem occurs when I build with MinGW (w64 9.0), g++, CMake (build types: Release and Debug). But I've tried to use MSVC (x86) and everything works fine.