Hi! As described in the PR, if two argument erase is removing the last element of one bucket (i.e. the one referenced in _M_buckets array for the next bucket) and then at least one element from the following bucket, but not all elements from that next bucket, __is_bucket_begin is initially false and in the second for (;;) iteration, while it is already true, __n_bkt == __bkt and thus _M_remove_bucket_begin doesn't do anything, and following if (__n && __n_bkt != __bkt) is false as well (1 && 0), thus nothing is changed in the _M_buckets array and we end up referencing there a removed element. We might crash if we read it and if we modify it, we usually corrupt malloc data structures.
Fixed thusly, if __is_bucket_begin is true, then we know __n is the first item in its bucket and thus __prev_n should be in the _M_buckets array. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2012-01-18 Jakub Jelinek <ja...@redhat.com> PR libstdc++/51845 * include/bits/hashtable.h (_Hashtable<>::erase(const_iterator, const_iterator)): Also update _M_buckets[__n_bkt] if __is_bucket_begin. --- 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); Jakub