Re: [Boost-users] shared_ptr + const_cast woes
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@gmail.com> Subject: Re: [Boost-users] shared ptr + const_cast woes To: boost-users@lists.boost.org Message-ID: <fa28b9250606280733u5125fa01p92da87e1e8f9ad0f@mail.gmail.com> 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@c-core.ca> Subject: Re: [Boost-users] shared ptr + const_cast woes To: boost-users@lists.boost.org Message-ID: <44A29238.9040800@c-core.ca> 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
participants (1)
-
Evan Drumwright