hash_map中迭代器问题

使用STL的hash_map也有几年的时间了(这里主要指SGI的STL库,Microsoft的可能实现方式有点区别)

我的代码中经常会出现这样的一段

hash_map<.,.>::iterator iter,itertemp;

for(  iter = h.begin();iter!=h.end();)

{

      itertemp = iter++;

     if( (*itertemp ).second == vaule ) 

     {

         h.erase(itertemp );

     }

今天突然发现身边的同事不是这样用的,他们给我提出了一个问题,

   h.erase(itertemp ); 有可能会导致迭代器iter失效.

    有这个可能吗?

  察看了一下hash_map中的迭代器的实现

 struct   _Hashtable_iterator

{

 

.....

 

...

  _Node* _M_cur;
  _Hashtable* _M_ht;  

};

其中只列出了我们关心的 两个成员,一个是 _M_cur,   _M_ht,说正确点,其实只关心  _M_cur;

_Node的实现也可以在STL的源代码中找到,这里就不列出来了,它实际上是一个单向连表

_Node结构主要包括2个成员

_M_next ,指向下一个成员

_M_val ,指向节点所关联的数据值,这里其实就是一个pair

 

分析一下++操作

_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
{
  const _Node* __old = _M_cur;
  _M_cur = _M_cur->_M_next;
  if (!_M_cur) {
    size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
    while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
      _M_cur = _M_ht->_M_buckets[__bucket];
  }
  return *this;
}

迭代器的++操作,实际上都是对内部的单向链表进行操作的,只是将链表指向下一个节点

迭代器本身不会做什么.

erase 操作也是这样的

template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
{
  _Node* __p = __it._M_cur;
  if (__p) {
    const size_type __n = _M_bkt_num(__p->_M_val);
    _Node* __cur = _M_buckets[__n];

    if (__cur == __p) {
      _M_buckets[__n] = __cur->_M_next;
      _M_delete_node(__cur);
      --_M_num_elements;
    }
    else {
      _Node* __next = __cur->_M_next;
      while (__next) {
        if (__next == __p) {
          __cur->_M_next = __next->_M_next;
          _M_delete_node(__next);
          --_M_num_elements;
          break;
        }
        else {
          __cur = __next;
          __next = __cur->_M_next;
        }
      }
    }
  }
}

实际操作都是里面 _Node成员

如果一个迭代器导致另外一个迭代器失效,

一种是导致另外一个迭代器的_Node成员的值发生变化,或者导致另外一个迭代器的 _Node成员失效,这里我们看到

erase操作并不能造成这样的效果.

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值