Boost logo

Boost Users :

From: Evan Drumwright (edrumwri_at_[hidden])
Date: 2006-07-04 14:51:12


Hi guys,

Thanks for your help, in particular Stefan's reworked code fragment. I
actually did read the documentation for shared_ptr (in particular, the
section on const_pointer_cast), but got confused by the counterexample (I
thought that it was saying not to use a temporary).

Thanks again,
Evan

>Message: 5
>Date: Wed, 28 Jun 2006 10:33:19 -0400
>From: me22 <me22.ca_at_[hidden]>
>Subject: Re: [Boost-users] shared ptr + const_cast woes
>To: boost-users_at_[hidden]
>Message-ID:
        <fa28b9250606280733u5125fa01p92da87e1e8f9ad0f_at_[hidden]>
>Content-Type: text/plain; charset=UTF-8; format=flowed

>Take a closer look at what this is doing:
>> boost::shared_ptr<const int> y(const_cast<const
>int*>(x.front().get()));
>To be more explicit, it's the same as
> int *ip = x.front().get();
> int const *cip = ip;
> boost::shared_ptr<const int> y( cip );
>At y you're creasing another shared_ptr to the same address that
>doesn't share ownership with the one in x.front().
>
>What you really want is const_pointer_cast :
>http://boost.org/libs/smart_ptr/shared_ptr.htm#const_pointer_cast
>
>From the documentation for the above-mentioned const_pointer_cast:
>Notes: the seemingly equivalent expression
>shared_ptr<T>(const_cast<T*>(r.get()))
>will eventually result in undefined behavior, attempting to delete the same
>object twice.
>Which is exactly your problem.
>
>~ Scott McMurray

------------------------------

>Message: 6
>Date: Wed, 28 Jun 2006 11:59:12 -0230
>From: Stefan Tarrant <stefan.tarrant_at_[hidden]>
>Subject: Re: [Boost-users] shared ptr + const_cast woes
>To: boost-users_at_[hidden]
>Message-ID: <44A29238.9040800_at_[hidden]>
>Content-Type: text/plain; charset=ISO-8859-1; format=flowed

>When you use get() all bets are off. You are basically taking
>responsibility for the ownership of the returned pointer yourself, which is
>generally a bad idea. Use a const_pointer_cast<T> instead.

>Here is my re-worked example:
>
>#include <vector>
>#include <iostream>
>#include <boost/shared_ptr.hpp>
>
>int main()
>{
> std::vector<boost::shared_ptr<int> > x;
> x.push_back(boost::shared_ptr<int>(new int));
> *x.front() = 4;
> std::cout << "use count: " << x.front().use_count() << std::endl;
> boost::shared_ptr<const int> y = x.front();
> std::cout << "use count: " << x.front().use_count() << std::endl;
> std::cout << "use count: " << y.use_count() << std::endl;
> boost::shared_ptr<int> z = boost::const_pointer_cast<int>(y);
> std::cout << "use count: " << z.use_count() << std::endl;
> std::cout << "use count: " << y.use_count() << std::endl;
> x.pop_back();
> std::cout << *y << std::endl;
> std::cout << "use count: " << z.use_count() << std::endl;
> std::cout << "use count: " << y.use_count() << std::endl;
>
> y.reset();
> std::cout << "use count: " << z.use_count() << std::endl;
> std::cout << "use count: " << y.use_count() << std::endl;
>}
>
>And the output:
>
>use count: 1
>use count: 2
>use count: 2
>use count: 3
>use count: 3
>4
>use count: 2
>use count: 2
>use count: 1
>use count: 0
>Press any key to continue . . .
>
>--
>Stefan Tarrant
>Senior Project Engineer
>C-CORE
>Captain Robert A. Bartlett Building
>Morrissey Road
>St. John's, NL
>Canada A1B 3X5


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net