Object deleted when its member function is being e

2020-07-11 04:52发布

I have pointer object to singleton class.

Thread 1: Currently executing a member function of the above said object.
Thread 2: Deletes the above object when the object's member function is still being executed by Thread 1.

What happens to Thread 1 where the member function is being executed? Whether the execution will be stopped midway?

4条回答
小情绪 Triste *
2楼-- · 2020-07-11 05:43

Undefined behavior is the right answer. To avoid such things consider using smart pointers, like this: http://www.boost.org/doc/libs/1_54_0/libs/smart_ptr/shared_ptr.htm or this: http://en.cppreference.com/w/cpp/memory/shared_ptr. They have reference counting mechanism that doesn't allow you to delete using object.

查看更多
地球回转人心会变
3楼-- · 2020-07-11 05:45

It is probably undefined behavior, unless you are extra careful.

Deleting the object while your thread accesses it in an unordered (non-synchronized, basically) manner is undefined behavior, even if you get lucky.

Accessing the members of the object (not just running a member: actually accessing a member -- calling a member function, reading a member variable, etc) after you have synchronized with the delete from the main thread is also undefined behavior.

If you carefully synchronize with the main thread, then do not access the member data nor call a different member function after that synchronization, and the main thread deletes the object after that synchronization, then you are perfectly ok.

Almost anything short of that results in undefined behavior.

While undefined behavior can do almost anything, it would be unexpected undefined behavior for this to cause the execution of the code in the member function to suddenly stop just because the object is deleted. More likely you'd get segfaults, memory corruption, or the like. What is worse is that in many cases, things would work "just fine".

查看更多
▲ chillily
4楼-- · 2020-07-11 05:46

You will most likely get undefined behavior. Thread 1 can get a seg fault or it may continue merrily on its way if it accesses no member data (and makes no virtual function calls) after the object's deletion. It also depends on what happens to the memory area after deletion. Is it cleared? Is it non-writable/non-readable? It's all highly implementation dependent as well dependent on the data needs of your application in terms of reusing the data area to handle other allocations.

The guidance is to never delete an object until all use of it is complete. There are some exceptions where member functions delete the object they operate on ensuring there is no more member access after the point of deletion. But other than those few cases that actually justify deletion in a member, don't do this.

In the multi-threaded environment you are describing, be absolutely certain to coordinate object lifetime with object use or you may get very difficult to debug (platform dependent and non-deterministic) behavior.

查看更多
爷的心禁止访问
5楼-- · 2020-07-11 05:57

Short answer: You shouldn't do this... You need to make sure the object is not being used before deleting it.

In terms of what the C++ standard specifies, it's (probably) undefined behaviour - something unexpected may well happen. The basis for this is that it's undefined behaviour to use any member (function or variable) of an object after the object has been destroyed. Of course, if the member function looks like this:

void foo::func()
{
   for(;;)
   {
     // do nothing here 
   }
}

then it's NOT undefined behaviour, and the thread can be left running indefinitely, without any ill effect, and the behvaiour (I believe) is well defined (it just keeps running).

Certainly thread 1's execution will definitely not stop simply because the object is being deleted. That is, unless the object actually contains a thread object for thread 1 - in which case, the destructor of the thread object may kill the thread.

In practice, if the object is deleted, it's memory is freed, and the memory may well be reused for some other object a small amount of time later. Depending on what the member function is doing, e.g, what parts of the object it's referring to, and how it's using those members, it may cause a crash, or if it does something like x++; (where x is a member variable), it will modify some memory it no longer is the owner of - and that can be quite tricky to debug, because it will appear like something is randomly changing other objects... This is definitely NOT good (and most likely, it will only happen SOMETIMES, making it really hard to spot when it goes wrong).

Nothing good can possibly come out of this.

You MUST make sure the object is not in use in any way to delete it. One way to do that is of course to have the thread object for thread 1, and kill the thread.

查看更多
登录 后发表回答