Boost logo

Boost Users :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2006-12-20 12:09:04


Joaquín Mª López Muñoz ha escrito:

> Hello John,
>
> johneddy101_at_[hidden] ha escrito:
>
>> I'm running into a problem while using hashed indices in a container
>> storing shared_ptr's.
>> The problem is occuring in the hashed_index::erase(key) method in
>> both the 1_33_1
>> release and the CVS head version. This is what the problem seems to
>> be:
>>
>> It is possible that the call to erase (or final_erase_) occurring
>> within the do loop
>> causes destruction of the passed in key object. The key object (k)
>> is then used in a
>> comparison in the while portion of the loop (y!=x&&eq(k, key(…))).
>> The default predicate uses
>> == in this comparison but one of the items (the left hand side) will
>> have already been destroyed.
>
> Umm... Thank you for spotting this, indeed the key passed to erase()
> can become
> invalid during the process if it physically belongs to one of the
> elements to be
> erased. Matter of fact, the problem is not specifically related to
> shared_ptr's.
>
> I don't know if it's too late to try to fix this on time for Boost
> 1.34; in case I find
> the time and permission to do it I'll let you know.

An update on this. The following rewrite of erase(key) in
hashed_index.hpp
should clear the problem:

  size_type erase(key_param_type k)
  {
    BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;

    size_type s=0;
    std::size_t buc=buckets.position(hash(k));
    hashed_index_node_impl* x=buckets.at(buc);
    hashed_index_node_impl* y=x->next();
    while(y!=x){
      if(eq(k,key(node_type::from_impl(y)->value()))){
        bool b;
        do{
          hashed_index_node_impl* z=y->next();
          b=z!=x&&eq(
            key(node_type::from_impl(y)->value()),
            key(node_type::from_impl(z)->value()));
          this->final_erase_(
            static_cast<final_node_type*>(node_type::from_impl(y)));
          y=z;
          ++s;
        }while(b);
        break;
      }
      y=y->next();
    }
    return s;
  }

Would you mind pasting this into your local copy of hashed_index.hpp
(CVS version) and report whether your prior problems get solved?

I'm writing a testcase for the issue and running my entire regression
tests, if
everything goes OK I think I'll be able to commit this into the CVS
before
the week ends.

Thank you,

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net