Boost logo

Boost :

From: Michael Grundberg (michaelgrundberg_at_[hidden])
Date: 2003-10-23 01:59:37


Hi,

I'm not sure whether this is supposed to go to this mailing list or to
the user mailing list, I'm sorry if I posted it to the wrong list. I
have also searched the mailing list archive and looked through the docs
but not finding an answer to my question.

Anyway, I'm wondering how it comes that the operator < of
boost::shared_ptr is comparing the pointers to the shared_counters
instead of the stored pointers themselves? The docs states that it
allows shared_ptr to be used as keys in associative containers. But
wouldn't a less operator defined as comparing the stored pointers also
allow the shared_ptr be used as keys in associative containers?

The reason I am asking this is that at work we recently switched from
using another pointer library to only use the smart pointers of boost,
and then mostly shared_ptr. It's being used amongst other things as an
interface pointer between libraries; a library wants a resource but
doesn't care how it's allocated, thus the library takes a shared_ptr to
the resource as parameter and the user can define whether the resource
will be dynamically allocated or statically allocated (and shared to the
library using a shared_ptr with a null_deleter). The problem we have is
that the libraries often uses std::set to store these resource pointers.
Now, if the user has given a library a pointer to a statically allocated
resource and wants the library to stop using the resouce, he will call
some function in the library, giving the library a new shared_ptr
pointing to the same statically allocated element. The library will call
std::set::erase, which will not find the pointer since the shared_ptr's
aren't the same even if the pointers are.

In other words, we do:

// Our resource
int i;

// Give it to the library
boost::shared_ptr<int> p1(&i, null_deleter());
std::set<boost::shared_ptr<int> > s; s.insert(p1);

// A bit later
boost::shared_ptr<int> p2(&i, null_deleter());
s.erase(p2);

Which doesn't remove the pointer from s. This is causing us alot of
bugs, since the compilations succeed but the code is broken.

Also, the definition of the less operator for shared_ptr causes
std::set::find and std::find to operate in different ways, since the
later uses the == operator instead of <. Was this the intent?

There are a few solutions to this problem of course, but I'm curious to
know what the logic is behind this behaviour. Would it be safe for us in
our projects to alter the behavior of the shared_ptr less operator? Does
anyone know whether any other code in boost uses that operator? That
would be the simplest solution for us anyway, since the code base is
huge.

Thank you for taking your time!

Michael Grundberg
Systems developer at SAAB, Sweden


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