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 に答える