Boost logo

Boost :

From: Gary Powell (Gary.Powell_at_[hidden])
Date: 2001-05-16 14:05:25


This bug also appears to be in shared_array::operator=()

> -----Original Message-----
> From: Greg Colvin [SMTP:gcolvin_at_[hidden]]
> Sent: Wednesday, May 16, 2001 7:53 AM
> To: boost_at_[hidden]
> Subject: Re: [boost] Problem with shared_ptr
>
> From: Beman Dawes <bdawes_at_[hidden]>
> > At 03:29 AM 5/16/2001, Thomas Maeder wrote:
> >
> > >This problem report is a result of a discussion in
> > >news://newsgroups.borland.com/borland.public.cppbuilder.language
> > >
> > >The following program demonstrates it, using boost 1.21.1 and gcc
> 2.95.3:
> > >
> > >#include <iostream>
> > >
> > >#include "boost/smart_ptr.hpp"
> > >
> > >struct S
> > >{
> > > ~S()
> > > {
> > > std::cout << "~S()\n";
> > > }
> > >
> > > boost::shared_ptr<S> next;
> > >};
> > >
> > >int main()
> > >{
> > > boost::shared_ptr<S> head(new S);
> > > head->next.reset(new S);
> > > std::cout << "before assignment\n";
> > > head = head->next;
> > > std::cout << "after assignment\n";
> > >}
> > >
> > >The output is
> > >
> > >before assginment
> > >~S()
> > >~S()
> > >after assginment
> >
> > Ouch!
>
> Amen.
>
> > >while one would expect it to be
> > >
> > >before assignment
> > >~S()
> > >after assignment
> > >~S()
> > >
> > >The reason is that the shared_ptr copy-assignment operator first
> reduces
> > >the reference count of the previously owned object and only then
> > increases
> > >that of the newly owned object; if both objects are the same, strange
> > >things happen.
> >
> > It isn't really a case of both objects being the same, but that the
> right
> > hand object is transitively dependent on the left hand object.
> >
> > The code causing the problem is:
> >
> > void share(T* rpx, long* rpn) {
> > if (pn != rpn) { // Q: why not px != rpx? A: fails when both == 0
> > dispose();
> > px = rpx;
> > ++*(pn = rpn);
> > }
> >
> > My first reaction is to change it to:
> >
> > void share(T* rpx, long* rpn) {
> > if (pn != rpn) { // Q: why not px != rpx? A: fails when both == 0
> > ++*rpn; // done before dispose() in case rpn transitively
> > // dependent on *this (bug reported by Thomas Maeder)
> > dispose();
> > px = rpx;
> > pn = rpn;
> > }
>
> This looks right to me.
>
>
> > I'll have give it a bit more thought. Greg? Also do some testing. The
>
> > test program needs updating anyhow.
> >
> > Thanks for the bug report.
> >
> > --Beman
>


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