A thread local variable has unexpected value during destruction

Viewed 117

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.

0 Answers
Related