This happens with both hash_map and unordered_map and their related classes.  I
know that hash_map is not standard, and unordered_map is in TR1 so not
considered standard yet.

Here is a kernel of the problem:

  hash_map<string,int> c;
  c.insert(...);
  hash_map<string,int>::iterator it = c.find("...");
  c.erase(it->first);

This is deleting by key value, not by iterator.

it->first is a key value which belongs to the collection object.
hash_map::erase(const key&) takes the key by reference.  It delegates to its
rep object, which is a hashtable.  hashtable::ref looks like this in gcc 4.0.2:

  if (__first)
    {
      ...
      while (__next)
        {
          if (_M_equals(_M_get_key(__next->_M_val), __key))
            {
              ...
              _M_delete_node(__next);
              ...
            }
          ...
        }
     ...
    }

The actual key object is in a node of the hash table.  After deleting that
node, the while() loop keeps using the deleted __key value with every other
node in the same bucket.

The following gcc versions have this problem with the following classes:

  gcc 3.4.5
    hash_map, hash_multimap, hash_set, hash_multiset

  gcc 4.0.2
  gcc 4.1-20060106
  gcc 4.2-20060114
    hash_map, hash_multimap, hash_set, hash_multiset
    unordered_map, unordered_multimap, unordered_set, unordered_multiset

You could punt on hash_map and friends because they are non-standard, but it is
nasty to have a case where code compiles and links and runs and then a library
function reads a destroyed object.  unordered_map and friends will eventually
(probably) be standardized so they are more serious.


-- 
           Summary: hash_map::erase, unordered_map::erase fail if key is
                    inside the table
           Product: gcc
           Version: 4.0.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: mec at google dot com
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25896

Reply via email to