3

私はリストをウォークスルーしようとしています。ここにいくつかの宣言があります:

list<CG1_Edge*> ActiveEdges;
list<CG1_Edge*>::iterator ActiveEdgeIterator;

時々、このコードは2行目でsegfaultsします。

for (this->ActiveEdgeIterator = this->ActiveEdges.begin(); this->ActiveEdgeIterator != this->ActiveEdges.end(); ++this->ActiveEdgeIterator) {
    CG1_Edge* currentEdge = *this->ActiveEdgeIterator;
    if (currentEdge->y_up < y)
        this->ActiveEdges.erase(this->ActiveEdgeIterator);
}

これがセグメンテーション違反につながる可能性がある一般的な理由はありますか?

4

2 に答える 2

5

次のようなものを使用する必要があります。

for (this->ActiveEdgeIterator = this->ActiveEdges.begin(); this->ActiveEdgeIterator != this->ActiveEdges.end(); ) {
    CG1_Edge* currentEdge = *this->ActiveEdgeIterator;
    if (currentEdge->y_up < y)
        this->ActiveEdgeIterator = this->ActiveEdges.erase(this->ActiveEdgeIterator);
    else
        ++this->ActiveEdgeIterator;
}

消去は次の要素に配置されたイテレータを返すためです。

(注: その反復子をメンバーとして持つのは奇妙に見えます。)

于 2011-04-03T09:57:19.783 に答える
0

Begemoth のコメントは、受け入れられた回答である必要があります。標準によると、消去は「すべてのイテレータと位置の後の要素への参照」を無効にします私の間違いです。これはベクトルとおそらく他のコンテナのためでした。少なくとも驚きを避けるために、代わりにアルゴリズムバージョンを使用することをお勧めします)。

したがって、すでに rbegin() と rend() を使用しているほうが安全です。しかし、なぜ std::alogirthms を使用しないのですか!

struct Predicate 
{
     int _y;
     explicit Predicate(int y) : _y(y) {}

     bool operator()(const CG1_Edge edge) const
     {
          return currentEdge->y_up < _y;
     }
};

std::erase(
     std::remove_if(this->ActiveEdges.begin(), this->ActiveEdges.end(), Predicate(y)),
     this->ActiveEdges.end());
于 2011-04-03T10:57:52.840 に答える