Boost logo

Boost :

From: Thomas Witt (witt_at_[hidden])
Date: 2002-09-09 11:34:15


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Monday 09 September 2002 17:13, Peter Dimov wrote:
> From: "Thomas Witt" <witt_at_[hidden]>
>
> > ptr != p should be a precondition violation.
>
> I agree (which is why shared_ptr's reset acts the way it does now), but...
>
> > I can't think of a good reason
> > why a scoped_ptr should be reset with a pointer that is already taken
> > care
>
> of
>
> > by a scoped ptr.
>
> ... the reason for the current behavior is std::auto_ptr compatibility.
> auto_ptr::reset is required to check for self-resets.
>
> > The current code fails if the dtor is called during a call to reset. Yes,
> > things like this can happen. The managed ptr will be deleted twice.
>
> If you can demonstrate this with an example, you may be able to convince
> Beman and Greg that scoped_ptr doesn't need to check for self-resets. :-)
>

FWIW here is the example.

!! untested code !!

class B;

class A
{
public:
  A(weak_ptr<B> b)
    : b_(b)
  {
  }

private:
  weak_ptr<B> b_;
}

class B :
  public detail::counted_base
{
public:
  a const& a()
  {
    if (!a_) {
      shared_ptr<B> self(intrusive_ptr<B>(this));

      a_.reset(new A(self));
    }
    return a_;
  }

  void dispose()
  {
    // We need to implement dispose as B dtor will
    // not be called unless weak_count == 0
    a_.reset()
  }

private:
  scoped_ptr<A> a_;
};

int main()
{
  intrusive_ptr<B> b(new B);

  // Create an A in B
  b->a();

  // b goes out of scope and all ends up in disaster.
}

What actually happens at end of main is

1) b goes out of scope
2) the shared_count of the B object goes to zero
3) B::dispose gets called
4) scoped_ptr<A>::reset deletes the A object the first time.
5) The destructor for A::b_ gets called
6) the weak_count for the B object goes to zero
7) The destructor for the B object is called.
8) the destructor for B::a_ is called
   Note that we are still in scoped_ptr<A>::reset
   scoped_ptr<A>::ptr still points to the A object
   that is currently destructed.
10) scoped_ptr<A>::~scoped_ptr<A> calls the destructor
    for ptr the second time.
11) We have managed to wreck the heap.

This might not be the most clever design, but still I think it is not abuse.
The real world example is a lot more complicated.

- --Thomas

- --
Dipl.-Ing. Thomas Witt
Institut fuer Verkehrswesen, Eisenbahnbau und -betrieb, Universitaet Hannover
voice: +49(0) 511 762 - 4273, fax: +49(0) 511 762-3001
http://www.ive.uni-hannover.de
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9fM2L0ds/gS3XsBoRAkM5AJ9AtkzRvbRGIpyM749RxIThykDwAwCfdos5
ZYVhWGS5Sm+w8IpMrndGQfY=
=Thra
-----END PGP SIGNATURE-----


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk