1

I'm trying to see what happens when an object is destroyed during thread execution.

While thread_ executes f, X is destroyed.

Can someone explain why End is displayed and the program doesn't stop with a segfault?

execute-1
f-1
f-2
DestrX
End
#include <iostream>
#include <thread>
using namespace std;
    
struct X 
{   
    void execute()
    {
        std::cout<<"execute-1\n";
    }
    void f()
    {
        std::cout<<"f-1\n";
        std::this_thread::sleep_for(std::chrono::seconds(5));
        std::cout<<"f-2\n";
    }
    ~X()
    {   
        std::cout<<"DestrX\n";
    }
};
    
int main()
{   
    std::thread thread_;
    std::shared_ptr<X> x = std::make_shared<X>();
    thread_ = std::thread(
        [&]()
        {
            x->f();
        });
    x->execute();
    x.reset();
    thread_.join();
    std::cout<<"End\n";
        
    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
John Marek
  • 11
  • 1
  • 12
    Not crashing is a perfectly valid manifestation of Undefined Behaviour. – Thomas Apr 19 '22 at 14:41
  • 1
    Very similar to [Is "delete this" allowed in C++?](https://stackoverflow.com/questions/3150942/is-delete-this-allowed-in-c) – Richard Critten Apr 19 '22 at 14:43
  • Remember that memory is usually allocated from an OS in pages. Usually a page is a few Kb. Not every delete will give the OS back the memory so the existing location may still be there. – drescherjm Apr 19 '22 at 14:46
  • 3
    `f` doesn't access any member data. What "segment" is meant to "fault" exactly? – StoryTeller - Unslander Monica Apr 19 '22 at 14:49
  • 1
    *"Can someone explain why End is displayed and the program doesn't stop with segfault ?"* - Because you didn't try hard enough? Lest you think law enforcement will never track you down, [see here](https://godbolt.org/z/vrnxzc85Y). And note, even *that* isn't "guaranteed" to crash. Invoking undefined behavior isn't guaranteed to do *anything* (thus nature of having no definition of behavior). – WhozCraig Apr 19 '22 at 14:51
  • thanks for all coments, I see that using bind the program will not crash, https://godbolt.org/z/zWsP94E1s. Is that guaranted that this program will not crash with bind and why exactly? I saw destructor is not called before the thread finishes. – John Marek Apr 19 '22 at 15:06
  • 1
    ***Is that guaranted that this program will not crash with bind and why exactly?*** Undefined behavior means anything can happen. It does not mean it will crash. The worst behavior is when UB produces a result that appears to look like the program is running fine and producing correct results. This gives you a false sense that your code is correct when its behavior could change at any time even without you changing a single line of code or even recompiling. – drescherjm Apr 19 '22 at 15:30
  • 1
    @JohnMarek You can't determine the *absence* of undefined behaviour by observing a program's behaviour. – molbdnilo Apr 19 '22 at 15:31
  • 3
    Crashes are a divine blessing from whatever deity you believe in. They tell you with no doubt that you have a problem. – user4581301 Apr 19 '22 at 15:34
  • actually I want to know if I can have a defined behaviour for such a case when object is reset while other thread is still using it, that's what I want to know if using bind it will become safe or such program has still undefined behaviour ? – John Marek Apr 19 '22 at 15:52
  • @JohnMarek by using `std::bind`, you *copy* the `shared_ptr`, so you don't actually release it at the point of `reset` – apple apple Apr 19 '22 at 15:57
  • @JohnMarek "*can [I] have a defined behaviour for such a case when object is reset while other thread is still using it*" - `reset()`ing a `shared_ptr` decrements its reference count, and only when the count falls to 0 will the held object then be destroyed. It is possible to `reset()` a `shared_ptr` that is still in use. The management of the reference count is thread safe. But there is nothing you can do to make destroying a object that is in use have well-defined behavior. If you want to `bind()` the `shared_ptr`, fine, but do so in a way that increments its reference count. – Remy Lebeau Apr 19 '22 at 16:52

0 Answers0