0

I'm using lower_bound() for searching in sorted vector of weak_ptr

vector<weak_ptr<A> >::iterator findA( const string & id ) const
{
    sa = make_shared<A>( id );
    a = sa;
    return lower_bound( owners.begin(), owners.end(), sa,
            [] ( const weak_ptr<A> & l, const weak_ptr<A> & r ) 
                {
                    return (l.lock()->getID() < r.lock()->getID());
                } );
}

Where sa is a shared_ptr<A>, class A has got a private string ID and a public method getID. When findA calls getID it causes segfault. I guess it's because of lock(), which retruns empty shared_ptr.

How can I fix it?

  • what is `sowner` ? you're not using `sa` in this piece of code. – Jagannath Apr 05 '15 at 23:00
  • I don't think the algorithm `std::lower_bound` is appropriate when elements of the range can be invalid (expired), since `lower_bound` requires the range to be partitioned. Additionally, I'm not sure if your return type can be useful to the caller: returning a `weak_ptr` does not guarantee that there is an object the weak pointer refers to, so `findA`'s guarantee is rather weak (it does not return the a pointer to the object with the *largest* existing `id` smaller or equal to the requested `id`). – dyp Apr 06 '15 at 01:13

1 Answers1

1

You can't sort elements whose value is not deterministic (and values stored in weak_ptr's are not deterministic). So you have no way of knowing that the vector is sorted.

If you do know that it is sorted (because the objects only go out of existence in the same thread in which you are calling lower_bound), then you need to be sure that

  1. the vector is sorted in such a way that all empty weak_ptr's are less than all non-empty ones.
  2. that the all empty weak_ptr's are not less than each other.
  3. the same comparator is used for both the sorting of the vector and for lower_bound function.

If you can't make the gurantee that the order of the elements stays the same (under the above comparator) before and after your call to lower_bound, then you can't use lower_bound.

In other words, you can get around the fact that lock will return an empty pointer by checking for it and handling it appropriately in the comparator, but you shouldn't do that if your objects are disappearing in a different thread (because then your order is not deterministic).

Dmitry Rubanovich
  • 2,471
  • 19
  • 27