|
Boost : |
From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-01-17 14:56:59
----- Original Message -----
From: "Tom Becker" <voidampersand_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Thursday, January 17, 2002 2:02 PM
Subject: [boost] Re: shared_ptr: unsafe, or am I crazy?
> On Thu, 17 Jan 2002 14:13:33 +0200, "Peter Dimov" <pdimov_at_[hidden]>
wrote:
> >From: "David Abrahams" <david.abrahams_at_[hidden]>
> > > struct Base { Base(); ~Base(); };
> > > struct Derived : Base { Derived(); ~Derived(); };
> > >
> > > void unsafe()
> > > {
> > > shared_ptr<Derived> d(new Derived);
> > > shared_ptr<Base> b(d);
> > > d.reset();
> > > b.reset(); // equivalent to delete (Base*)(new Derived)!!
> > > };
> >
> >It recently occured to me that this is another example that proves
release()
> >extremely dangerous.
> >
> >A smart shared_ptr can do the right thing on b.reset(), but on
b.release()
> >the user will be left with a Base* and the undefined behavior is not far
> >away.
>
> The problem is not in shared_ptr or release.
>
> Derived* d = new Derived;
> Base* b = d;
> delete b; // ouch!
>
> Deleting through a pointer that doesn't have adequate type
> information is bad. The code should either give Base a virtual
> destructor, or it should avoid slicing the Derived* to a Base*.
> Converting the code to use shared_ptr doesn't change its safety, or
> lack thereof, in any way.
I think many people regard smart pointers as a way of removing the unsafe
characteristics of raw pointers, by hiding them behind a well-behaved
interface. From that POV, eliminating release (and, for that matter,
construction from raw pointers) is a good idea.
-Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk