13

我正在写一个节点寻路算法。我需要运行一个多图并在某些条件下从中删除元素,但要继续遍历多图。下面是我到目前为止的代码,它似乎大部分时间都可以工作,但是在执行 nct_it++ 时偶尔会出错。在递增迭代器之前从表中擦除迭代器指针是否安全?

std::list<SinkSourceNodeConn>::iterator it;
std::multimap<SysNode*, SysNode*>::iterator nct_it;
SysNode* found_node = NULL;
nct_it = node_conn_table.begin();
while(nct_it != node_conn_table.end()) {

    // Find the node in the ever shrinking node connection table...
    if(nct_it->first == parent_node)
        found_node = nct_it->second;

    // Remove the table entry if we have found a node
    if(found_node) {
        // Search for the node in the expanded list. If it's not found, add it.
        bool found_the_node = false;
        for(it = m_sink_source_nodes_.begin(); it != m_sink_source_nodes_.end(); it++) {
            if(it->sink_source == sink_source && it->node == found_node)
                found_the_node = true;
        }
        if(!found_the_node) {
            recursion_list.push_back(found_node);
            recursion_list.unique();
            SinkSourceNodeConn ssnc;
            ssnc.node = found_node;
            ssnc.sink_source = sink_source;
            m_sink_source_nodes_.push_back(ssnc);
            if(found_node->GetPotential() < sink_source->GetPotential())
                found_node->SetPotential(sink_source->GetPotential());
        }
        found_node = NULL; // Unset the found node...
        node_conn_table.erase(nct_it);
        nct_it++;
    } else
        nct_it++;

}
4

2 回答 2

32

在递增迭代器之前从表中擦除迭代器指针是否安全?

不,erase会使迭代器无效,之后你不应该增加它。

要正确执行此操作,请使用erase- 最后一个删除元素之后的迭代器的返回值:

std::multimap<int, int> m;

for (auto it = m.begin(); it != m.end(); ) {
   if (condition)
       it = m.erase(it);
   else
       ++it;
}

在 C++03 中,erase不返回任何内容,因此您必须手动执行此操作,方法是保存迭代器的副本并在擦除原始副本之前将其递增:

std::multimap<int, int> m;
typedef std::multimap<int, int>::iterator Iter;¸

for (Iter it = m.begin(); it != m.end(); ) {
   if ( /* some condition */ ) {
       Iter save = it;
       ++save;
       m.erase(it);
       it = save;
   } else
       ++it;
}
于 2013-01-24T22:30:51.137 回答
0

这不是更好吗?

std::multimap<int, int> m;
typedef std::multimap<int, int>::iterator Iter;¸

for (Iter it = m.begin(); it != m.end(); ) {
    if ( /* some condition */ ) {
        Iter save = it;
        ++it;
        m.erase(save);
    } else
       ++it;
}
于 2019-12-30T20:27:40.840 回答