Re: Re-entering Release() - strange crash
Igor R. <igor.rubinov@gmail.com> wrote:
No, I debugged it thoroughly: release() is called excalty when it
should (otherwise the object would never be deleted!), and everything
works as expected. Except for the last accord.
On app. shutdown It goes like this:
// refcount == 2
Release()
InternalRelease() // now refcount == 1
release()
Release() // due to holder_.reset()
delete this;
return 0; // retval is discarded
return 1; // retval goes to the client(?); I tried to change it to 0
in the debugger -- it doesn't matter
I wonder if shared_ptr::reset implementation is prepared for its
shared_ptr instance to be destroyed from under it. In other words, I'm
curious how well this would work:
class C {
public:
void DeleteMe() { delete this; }
shared_ptr<C> holder_;
C() : holder_(this, mem_fn(&C::DeleteMe)) {}
void ResetHolder() { holder_.reset(); }
};
int main() {
C* p = new C;
p->ResetHolder();
return 0;
}
The issue here is that reset() calls DeleteMe, which destroys C, which
takes holder_ with it to the grave - while holder_.reset() is still on
the call stack. If reset() tries to access member variables of
shared_ptr after calling DeleteMe, it's in trouble.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925