0

私は単純な for ループを持っています:

for (int i = 0; i < c.numparticles; i++)
{
    if ( labs((noncollision[i].getypos())) > 5000 )
    {
        noncollision.erase (noncollision.begin()+i);
    }
}

はclassnoncollisionのベクトルですparticle。この特定の例でnoncollisionは、ypos5000 を超えるものはすべて消去する必要があります。noncollision私は6のサイズで作業しており、そのうち2つはypos5000をはるかに超えています。私の疑いはnoncollision、クラスのベクトルであるため、このクラスが何らかの形で保護されているか、配列関数の動作が異なるためでしょうか? noncollision、および の宣言は次のparticleとおりです。

vector<particle> noncollision;

class particle{
private:
int xpos;
int ypos;
int xvel;
int yvel;
bool jc; // Has the particle just collided?
public:
etc....
};

なぜこれが起こっているのか、そしてそれを修正する方法を誰かが説明できますか? particleクラスに「消去機能」を設定する必要がありますか?

4

3 に答える 3

1

「無効化されたイテレータ」症候群に苦しんでいるように見えますが、この場合、問題はインデックスです。

消去したい 2 つの要素が隣り合っていますか?

問題は、ベクターから要素を消去すると、残りの基になる要素が新しい場所にコピーされ (最後の要素を消去しない限り)、ベクター内の要素の数が 1 つ減ることです。

ベクトルへのインデックス付けを使用しているため、最初の問題 (イテレータが無効化されている) に反することはありませんが、次のようになります。

  • 消去したばかりの要素の直後に要素をチェックすることはありません
  • あなたのインデックスはベクトルの終わりからこぼれます(未定義の動作)

同じループで検査しているシーケンスを変更することは、悪い考えです。より良い方法については、remove_ifをご覧ください 。このアルゴリズムは、一致するすべての要素をベクトルの最後に配置し、移動された最初の要素へのイテレータを返します。これにより、一度にすべてを安全に削除できます。

于 2013-08-06T14:46:17.797 に答える