c++从指针向量中删除

c++ deletion from vector of pointers

本文关键字:删除 向量 指针 c++      更新时间:2023-10-16

我正在浏览Cinder的Box2D模板中的代码,并希望修改代码,以便在屏幕上删除框并添加它们。我是C++的新手,但根据我从其他SO帖子中学到的知识,我试图使用以下if case从向量中删除框:

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)->GetPosition().x"第二次执行时,这会导致坏的访问崩溃。有什么想法吗?

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

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

观察到这种行为的原因是因为向量的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++;
    }
}

请参阅此处:

矢量擦除(迭代器)导致错误的内存访问

迭代时删除

迭代向量,在进行时删除某些项目

您的问题是擦除迭代器,然后继续使用它进行迭代。

对于矢量every iterator and reference after the point of erase is invalidated.(此处对其他情况有很好的概述:http://kera.name/articles/2011/06/iterator-invalidation-rules/)

你可以尝试使用带有remove_if的擦除(后者本身并不能擦除任何东西)

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