0

Is it safe to call map::count on an uninitialized thus empty weak_ptr safe?

I'm still very inexperienced with c++ and do not have the skills to determine this.

In my application, a weak_ptr is being held as key in a map and must be found first by the values. If it cannot be found, an uninitialized weak_ptr is returned and used in map::count.

Code

Setup

map<my_ptr, connection_data, owner_less<my_ptr>> m_connections;
typedef map<my_ptr, connection_data, owner_less<my_ptr>>::iterator it;

Find by data

my_ptr get_my_ptr_from_data(string data){
    my_ptr my_ptr_to_send;
    for(it iterator = my_ptrs.begin(); iterator != my_ptrs.end(); iterator++) {
        if(iterator->second.data == data){
            my_ptr_to_send = iterator->first;
            break;
        }
    }
    return my_ptr_to_send;
}

Finding

my_ptr found_ptr = get_my_ptr_from_data(data);
if(my_ptrs.count(found_ptr) ){

1 Answers1

4

It's safe to call find (and count), as long as whatever ordering you've defined doesn't rely on the pointer being non-empty. The only thing that find (and count) will do with the argument is use it as an argument for the comparator.

However, it's not safe to use weak_ptr as a key in an associative container. If it expires, then the container's order is broken, and trying to use the container afterwards will give undefined behaviour.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • @Gracchus: No problem, the answer's the same for `count`, since that does more or less the same thing as `find`. – Mike Seymour Apr 18 '14 at 14:37
  • @Gracchus: It's either wrong (if there's any chance that the pointers could expire) or unnecessary (since, if they can't expire, you might as well store shared pointers, or even raw pointers). – Mike Seymour Apr 18 '14 at 14:43
  • If they cannot expire, storing shared_pointer's instead of raw pointers might add unneccessary overhead as would weak_pointer's for sure. – Deduplicator Apr 18 '14 at 14:49
  • @Deduplicator: I think shared pointers would have the same overhead as weak, but would remove any danger of expiry. Raw pointers would have less, and a different flavour of undefined behaviour if they did expire. – Mike Seymour Apr 18 '14 at 14:52
  • @MikeSeymour: On many implementations `sizeof(std::shared_pointer) == 2 * sizeof(T*)`, because fast access to the pointer is optimized over space consumption. (Somewhere it must save its shared counters). `std::weak_pointer` cannot do that optimization, because it must always ensure the object still exists, so it must access the counters anyway. – Deduplicator Apr 18 '14 at 15:06
  • @Gracchus: That's a bug any way you see it. – Deduplicator Apr 18 '14 at 15:08
  • One point that I think should be clarified: A `set` of weak_ptr is safe as long as you are using owner_less, since that relies on the underlying control object. That control object will not be deleted until all of the weak_ptr's are also destroyed. – Dave S Apr 18 '14 at 18:00