【问题标题】:iterator returned by std::find() is not dereferenceablestd::find() 返回的迭代器不可解引用
【发布时间】:2018-11-15 15:25:16
【问题描述】:

这是一个带有链接的 HashTable 实现的 insert() 函数。为了避免在linked_list 中重复,我检查了一个值是否已经存在。如果是这样,那么我只需替换现有值,因为它几乎可以在它“更新值”的末尾看到。该行发出一个异常,告诉我迭代器不可取消引用。为什么我不能取消引用 std::find() 返回的迭代器?还有其他方法可以更新找到的值吗?

virtual void insert(const K& k, const V& v) {
    auto index = hashFctn(k, m_table.capacity());
    if (needsToGrow() || m_table[index].m_list.size() >= m_load_factor) {
        rehash();
        insert(k, v);
    }
    else {
        auto it = std::find(m_table[index].m_list.begin(), 
                            m_table[index].m_list.end(), v);
        if (it != m_table[index].m_list.end()) { // if found add it
            m_table[index].m_flag = flag::IN_USE;
            m_table[index].m_key = k;
            m_table[index].m_list.push_back(v);
            m_nbrOfElements++;
        } else {
            *it = v; // update value if exists
        }
    }
}

【问题讨论】:

  • 我没有提到它,但很清楚(对我来说我猜)正在使用的链表是 std::list。

标签: c++ c++11 iterator c++-standard-library


【解决方案1】:

你有

if (it != m_table[index].m_list.end()) { // if found add it
    // Irrelevant...
} else {
    *it = v; // update value if exists
}

如果迭代器it 不是结束迭代器,你会做一些不相关的事情。但在 else 情况下,迭代器 it 等于结束迭代器,这是不可取消引用的。然而你取消引用它。

我认为条件应该相反,改用==

【讨论】:

  • 我认为我的问题是不能很好地理解 STL 的工作原理。我习惯于写我所有的东西,而不是按照我的教科书等等。那么,如果没有找到,std::find() 会返回 end(),否则返回一个有效的迭代器?
  • @blade 没错。
  • @blade:更准确地说,如果在x .. std::prev(y) 中找不到valuestd::find(x,y, value) 将返回y。这意味着它可以搜索子范围,然后如果未找到该值,它将返回子范围的结尾。这也意味着您可以将std::find 与没有.end() 成员函数的旧C 数组一起使用。
猜你喜欢
  • 2020-02-14
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-27
相关资源
最近更新 更多