Controlling/releasing ownership in shared_ptr



 DEVELOP > c-Plus-Plus > Controlling/releasing ownership in shared_ptr

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "digz"
Date: 16 Jan 2008 11:54:22 AM
Object: Controlling/releasing ownership in shared_ptr
In the code below , a simplified version
I need to pass a smart pointer to function f which I control .I
cannot use std::auto_ptr as a parameter to f because
it releases ownership on copy construction and I still need the
pointer after f returns.( may be I could return the auto_ptr
again ?? )
after f does its stuff , i need to pass it to g which expects a raw
pointer ( I cannot change that API )
I know g does maintain its own ptr_deque which takes care of
ownership etc.. ,
I am forced to do a get() on the shared_ptr ( instead of an ideal
release() on auto_ptr which would free the ptr from smart
management )
Now shared_ptr and ptr_deque desturctors cause a double delete
leading to UB.
How do i workaround this problem ?
Thx
Digz
#include<boost/shared_ptr.hpp>
#include<boost/ptr_container/ptr_deque.hpp>
boost::ptr_deque<int> l;
void f(boost::shared_ptr<int> t = boost::shared_ptr<int>())
{}
void g(int* i){
l.push_back(i);
}
int h(){
boost::shared_ptr<int> i(new int);
f(i); //need to pass aroung i, so cant use std::auto_ptr
g(i.get()); //cant release from boost::shared_ptr ownership
}
int main(){
h();
}
.

User: "Alf P. Steinbach"

Title: Re: Controlling/releasing ownership in shared_ptr 16 Jan 2008 12:35:52 PM
* digz:

In the code below , a simplified version
I need to pass a smart pointer to function f which I control .I
cannot use std::auto_ptr as a parameter to f because
it releases ownership on copy construction and I still need the
pointer after f returns.( may be I could return the auto_ptr
again ?? )

after f does its stuff , i need to pass it to g which expects a raw
pointer ( I cannot change that API )
I know g does maintain its own ptr_deque which takes care of
ownership etc.. ,

I am forced to do a get() on the shared_ptr ( instead of an ideal
release() on auto_ptr which would free the ptr from smart
management )
Now shared_ptr and ptr_deque desturctors cause a double delete
leading to UB.
How do i workaround this problem ?

#include<boost/shared_ptr.hpp>
#include<boost/ptr_container/ptr_deque.hpp>

boost::ptr_deque<int> l;

"l" is not a good name because it's easily confused with "1".

void f(boost::shared_ptr<int> t = boost::shared_ptr<int>())
{}

void g(int* i){
l.push_back(i);
}

int h(){
boost::shared_ptr<int> i(new int);
f(i); //need to pass aroung i, so cant use std::auto_ptr
g(i.get()); //cant release from boost::shared_ptr ownership
}

You can use std::auto_ptr for exception safety and ownership transfer.
Off-the-cuff, fix errors if any:
void f( int& ) {}
void transferOwnershipToG( std::auto_ptr<int> p )
{
int* pRaw = p.get();
p.release();
g( pRaw );
}
int h()
{
std::auto_ptr<int> p( new int );
f( *p ); // If f throws, std::auto_ptr deallocates.
transferOwnershipToG( p );
}
Or, with the current boost::shared_ptr interface you can release a
boost::shared_ptr by replacing its delete function. I think the
function to gain access to the deleter is named get_deleter. However,
this could be a bit dangerous, because with a shared_ptr at hand one
expects that it will handle deallocation and can be copied and stored
safely, which will not be the case in your code.
Cheers, & hth.,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
.
User: "James Kanze"

Title: Re: Controlling/releasing ownership in shared_ptr 17 Jan 2008 04:04:57 AM
On Jan 16, 7:35 pm, "Alf P. Steinbach" <al...@start.no> wrote:

* digz:

[...]

Off-the-cuff, fix errors if any:
void f( int& ) {}
void transferOwnershipToG( std::auto_ptr<int> p )
{
int* pRaw =3D p.get();
p.release();
g( pRaw );
}

Generally, I would do the release after the call to g(), i.e.:
g( p.get() ) ;
p.release() ;
Only if the call to g() succeeds can I be sure that it has taken
over ownership. Otherwise, you can just call g() directly:
g( p.release() ) ;
(Obviously, this depends partially on g(). Normally, in the
absence of other documentation, I would expect transactional
semantics, which means that if g() returns via an exception,
nothing has changed, and I am still responsible for the object.
But it's something I'd verify anyway.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34
.
User: "Alf P. Steinbach"

Title: Re: Controlling/releasing ownership in shared_ptr 17 Jan 2008 04:23:27 AM
* James Kanze:

On Jan 16, 7:35 pm, "Alf P. Steinbach" <al...@start.no> wrote:

* digz:


[...]

Off-the-cuff, fix errors if any:


void f( int& ) {}


void transferOwnershipToG( std::auto_ptr<int> p )
{
int* pRaw = p.get();
p.release();
g( pRaw );
}


Generally, I would do the release after the call to g(), i.e.:
g( p.get() ) ;
p.release() ;

Yup. I had a feeling there was something.

Only if the call to g() succeeds can I be sure that it has taken
over ownership. Otherwise, you can just call g() directly:
g( p.release() ) ;

Yup again -- otherwise no reason for having the transferOwnershipToG
wrapper.

(Obviously, this depends partially on g(). Normally, in the
absence of other documentation, I would expect transactional
semantics, which means that if g() returns via an exception,
nothing has changed, and I am still responsible for the object.
But it's something I'd verify anyway.)

Code above assumed failure reporting via exceptions.
Cheers,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
.




  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER