http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51845
--- Comment #17 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-18 18:51:57 UTC --- I think the bug is in the two argument erase in hashtable.h. In the testcase we are removing two elements, the last element from bucket 10 and first element from bucket 20, but there is also another element in bucket 20. This means that __is_bucket_begin is false initially, the last element from bucket 10 is removed, then __is_bucket_begin is set to true, but as we don't remove the whole bucket (we stop when __n_bkt == __bkt because we reach __last_n), the _M_remove_bucket_begin call does nothing. But as __n_bkt == __bkt, we dont' update _M_buckets[__n_bkt], so it references a removed node. --- libstdc++-v3/include/bits/hashtable.h 2012-01-15 20:59:53.765526939 +0100 +++ libstdc++-v3/include/bits/hashtable.h 2012-01-18 19:49:39.222388730 +0100 @@ -1541,7 +1541,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __bkt = __n_bkt; } - if (__n && __n_bkt != __bkt) + if (__n && (__n_bkt != __bkt || __is_bucket_begin)) _M_buckets[__n_bkt] = __prev_n; __prev_n->_M_nxt = __n; return iterator(__n); seems to fix this and I think it should be safe, when __is_bucket_begin is set, it means __n will be the bucket begin, so _M_buckets[__n_bkt] should be __prev_n. The __n_bkt != __bkt test is still needed, for the case where we remove just the trailing elements of some bucket, then we want to update the next bucket, even when __is_bucket_begin is false.