Boost logo

Boost Users :

From: johneddy101_at_[hidden]
Date: 2006-12-20 14:08:54


Joaquin,
Thanks for the quick response and the quick fix. I inserted your new code and everything seems to be fine. Prior to inserting the code, I was doing 150,000 insertions and subsequent erasures from a container. It would always fault at some point during the erasures but exactly where was unreliable. It does not seem to fault now even if I bump it up to 1,500,000 which is very strong evidence that your solution has worked.
Thanks again for the great lib,
John

Joaquín Mª López Muñoz ha escrito:
Hello John,
johneddy101 <at> comcast.net 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