2

My code:

{
    t = std::make_unique<std::thread>(std::bind(&Widget::generateNum, this));
}

crash at ~thread() , error msg is 'r6010 abort() has been called'. If I haven't call t.release() before that destructing t, will cause the crash.

Crawl.W
  • 403
  • 5
  • 17
  • 1
    Post the rest of the code. Something might be going out of scope. – user2296177 Jun 01 '17 at 01:51
  • 1
    The code you have shown isn't enough to determine the problem. – dreamlax Jun 01 '17 at 01:51
  • @dreamlax: Actually, not true. – Dietrich Epp Jun 01 '17 at 01:53
  • 1
    For those closing as "off-topic: why isn't this code working" I would like to point out that the code snippet will call `abort` as written, if you just add dummy definitions to make things compile and let `t` go out of scope. The only valid close reason for this question is "duplicate", but I wasn't able to find a duplicate question. I'm sure there is one. – Dietrich Epp Jun 01 '17 at 01:58
  • almost a duplicate (concerns pre-Standard `thread` class): https://stackoverflow.com/q/21502565/103167 – Ben Voigt Jun 01 '17 at 02:30
  • another near-dupe that explains why it works this way: https://stackoverflow.com/q/21334406/103167 – Ben Voigt Jun 01 '17 at 02:32
  • @Dietrich: This one looks like a duplicate, even involves unique_ptr: https://stackoverflow.com/q/25911734/103167 – Ben Voigt Jun 01 '17 at 02:33
  • I don't think my problem is dupe because my question related to `unique_ptr::release()`. – Crawl.W Jun 01 '17 at 02:34
  • and another: https://stackoverflow.com/q/7406596/103167 – Ben Voigt Jun 01 '17 at 02:35
  • @Crawl.W: `make_unique` is not a type, it's a function that returns `unique_ptr`. And the link you replied to DOES call `std::unique_ptr::release()`. – Ben Voigt Jun 01 '17 at 02:36
  • @BenVoigt slip of a pen, lol. – Crawl.W Jun 01 '17 at 02:38

1 Answers1

4

You must detach or join a thread before destroying it.

auto t = std::make_unique<std::thread>(std::bind(&Widget::generateNum, this));

// Either do this:
t->detach();
// or do this:
t->join();
// before *t gets destroyed.

The choice of whether to detach or join is up to you, but you must do one or the other. If a non-empty std::thread gets destroyed it will call std::terminate, ending your program.

See std::thread::~thread:

If *this has an associated thread (joinable() == true), std::terminate() is called.

The default std::terminate handler calls std::abort, hence the message that abort has been called.

Don't Call t.release()

It would be a mistake to call t.release(). This would leak the std::thread object.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • What you referred to is the cause of the crash and I know.But why 't.release()' will done well? – Crawl.W Jun 01 '17 at 02:04
  • 2
    Calling `t.release()` will leak the `std::thread` object. This avoids calling the destructor entirely, and leaks memory. Do not do this. – Dietrich Epp Jun 01 '17 at 02:05
  • While it's technically true that either joining or detaching the thread will eliminate this crash, detaching is almost never the right answer, especially for beginners. It's an advanced tool. – Pete Becker Jun 01 '17 at 02:35
  • @PeteBecker: In my experience, `.detach()` is not exceptional--and often `.join()` is just a poor substitute for `std::async`. Calling it an "advanced tool" is a matter of pedagogical opinion. – Dietrich Epp Jun 01 '17 at 02:44