C++ 安全地从指针向量中删除

C++ 安全地从指针向量中删除,c++,vector,iterator,C++,Vector,Iterator,好的,这可能是非常基本的,但我以前从未做过 我有一个Particles的向量,当它们离开可见屏幕时,我想擦除它们。我查阅了erase-remove习惯用法,但我不知道如何使其工作,因为我还需要删除粒子实例。我尝试了反向迭代,但没有成功: for ( std::vector<Particle*>::reverse_iterator rit = particles.rbegin(); rit != particles.rend(); ++rit ) { if ( IsOffScr

好的,这可能是非常基本的,但我以前从未做过

我有一个
Particle
s的向量,当它们离开可见屏幕时,我想擦除它们。我查阅了erase-remove习惯用法,但我不知道如何使其工作,因为我还需要删除
粒子
实例。我尝试了反向迭代,但没有成功:

for ( std::vector<Particle*>::reverse_iterator rit = particles.rbegin(); rit != particles.rend(); ++rit )
{
    if ( IsOffScreen((*rit)->pos) )
    {
        delete (*rit.base());
        particles.erase(rit.base());
    }
}
for(std::vector::reverse_迭代器rit=particles.rbegin();rit!=particles.rend();++rit)
{
if(IsofScreen((*rit)->pos))
{
删除(*rit.base());
粒子。擦除(rit.base());
}
}
在运行时崩溃时,VisualStudio说“迭代器不能递减”。我做错了什么?有更好的方法吗?

那么:

for (std::vector<Particle*>::iterator it = particles.begin(); it != particles.end(); ++it) {
    if (IsOffScreen((*it)->pos)) {
        delete *it;
        *it = NULL;
    }
}
particles.erase(std::remove(particles.begin(), particles.end(), NULL), particles.end());
for(std::vector::iterator it=particles.begin();it!=particles.end();+it){
if(IsofScreen((*it)->pos)){
删除*它;
*它=空;
}
}
particles.erase(std::remove(particles.begin()、particles.end()、NULL)、particles.end());
还有各种其他选项——例如,您可以在谓词中删除它们,因为IIRC保证在每个项上只运行一次

对于这类事情,您确实需要小心使用
remove
remove\u if
,因为删除的对象处于未定义状态,因此不可能
删除它们并在以后删除(您可以使用
std::partition
,但速度较慢)。

关于:

for (std::vector<Particle*>::iterator it = particles.begin(); it != particles.end(); ++it) {
    if (IsOffScreen((*it)->pos)) {
        delete *it;
        *it = NULL;
    }
}
particles.erase(std::remove(particles.begin(), particles.end(), NULL), particles.end());
for(std::vector::iterator it=particles.begin();it!=particles.end();+it){
if(IsofScreen((*it)->pos)){
删除*它;
*它=空;
}
}
particles.erase(std::remove(particles.begin()、particles.end()、NULL)、particles.end());
还有各种其他选项——例如,您可以在谓词中删除它们,因为IIRC保证在每个项上只运行一次


对于这类事情,您确实需要小心使用
remove
remove\u if
,因为被删除的对象处于未定义状态,所以不可能
删除它们,然后再删除(您可以使用
std::partition
,但速度较慢).

rit
不是有效的迭代器时,不能说
++rit
。您会发现的返回值对解决问题特别有帮助,因为它应该成为新的迭代器值,而不是在发生擦除时递增/递减现有迭代器值。按相反顺序使用索引。如果使用智能指针,则可以使用“擦除-删除”习惯用法,不再担心泄漏。@是的,我可以这样做,但是我以前想用很多粒子来衡量性能,比较智能指针和原始指针。当
rit
不是有效的迭代器时,你不能说
++rit
。你会发现的返回值对解决问题特别有帮助,因为它应该成为新的迭代器值,而不是在发生擦除时递增/递减现有迭代器值。按相反顺序使用索引。如果使用智能指针,则可以使用“擦除-删除”习惯用法,不再担心泄漏。@是的,我可以这样做,但是我以前想用很多粒子来衡量性能,并比较智能指针和原始指针。这会产生
错误C2446:“==”:在
std::algorithm
中没有从“const int”到“Particle*”的转换。也许它想要
(Particle*)NULL
?可以将std::remove_与修改要删除的元素的谓词一起使用;)@Peter是的,就是这样。这会产生
错误C2446:“==”:在
std::algorithm
中没有从“const int”到“Particle*”的转换。可能它想要
(Particle*)NULL
?如果有一个谓词修改要删除的元素,可以使用std::remove\u;)@彼得:是的,就是这样。