从指针向量中删除c ++

时间:2013-07-04 22:50:07

标签: c++ pointers vector iterator

我正在浏览Cinder的Box2D模板中的代码,并希望修改代码,以便我可以将框移到屏幕上并添加它们。我是C ++的新手,但基于我从其他SO帖子中学到的东西,我试图使用这个案例从矢量中删除框:

for( vector<b2Body*>::iterator boxIt = mBoxes.begin(); boxIt != mBoxes.end(); ++boxIt ) {
    if( (*boxIt)->GetPosition().x > scaledX){
        boxIt = mBoxes.erase(boxIt);
    }
    else {

        Vec2f pos( (*boxIt)->GetPosition().x, (*boxIt)->GetPosition().y );
        float t = toDegrees( (*boxIt)->GetAngle() );

        glPushMatrix();
        gl::translate( pos );
        gl::rotate( t );

        Rectf rect( -BOX_SIZE, -BOX_SIZE, BOX_SIZE, BOX_SIZE );
        gl::drawSolidRect( rect );

        glPopMatrix();
    }

}

但是当“(* boxIt) - &gt; GetPosition()。x”第二次执行时,这会导致访问崩溃。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

擦除后你不应该++boxIt。赋值已经将迭代器移动到下一个项目。

从for行中删除++boxIt并将其放入else

答案 1 :(得分:1)

您观察到此类行为的原因是因为向量erase()使现有迭代器无效。然后,您无法递增迭代器++boxIt。但是erase()返回一个新的迭代器,指向被删除的元素之后的元素。并且您可以使用此返回的迭代器继续迭代向量。

所以,你可能会这样编码:

vector<b2Body*>::iterator boxIt = mBoxes.begin();
while (boxIt != mBoxes.end();) {
    if( (*boxIt)->GetPosition().x > scaledX){
        boxIt = mBoxes.erase(boxIt);
    }
    else {

        Vec2f pos( (*boxIt)->GetPosition().x, (*boxIt)->GetPosition().y );
        float t = toDegrees( (*boxIt)->GetAngle() );

        glPushMatrix();
        gl::translate( pos );
        gl::rotate( t );

        Rectf rect( -BOX_SIZE, -BOX_SIZE, BOX_SIZE, BOX_SIZE );
        gl::drawSolidRect( rect );

        glPopMatrix();
        boxit++;
    }
}

见这里:

Vector.erase(Iterator) causes bad memory access

deleting while iterating

iterate vector, remove certain items as I go

答案 2 :(得分:0)

您的问题是您正在擦除迭代器,然后继续迭代它。

对于向量every iterator and reference after the point of erase is invalidated.(此处其他案例的概述:http://kera.name/articles/2011/06/iterator-invalidation-rules/

您可以尝试使用erase with remove_if(后者实际上不会删除任何内容)

http://en.wikipedia.org/wiki/Erase-remove_idiom