从 for 循环崩溃中的向量中删除?

Posted

技术标签:

【中文标题】从 for 循环崩溃中的向量中删除?【英文标题】:Deleting from vector in for loop crashes? 【发布时间】:2009-08-07 10:16:44 【问题描述】:

我在循环一个向量时遇到问题,从另一个向量中删除值有时会使我的程序崩溃。我有这个 int 向量来跟踪应该删除哪些元素。

std::vector<int> trEn;

然后我循环遍历这个向量:

struct enemyStruct 
    float x, y, health, mhealth, speed, turnspeed;
    double angle, tangle;
;
std::vector<enemyStruct> enemies;

循环如下所示:

for ( unsigned int i = 0; i < bullets.size(); i++ ) 
    for ( unsigned int j = 0; j < enemies.size(); j++ ) 
        if ( bullets[i].x > enemies[j].x-10 && bullets[i].x < enemies[j].x+10 && bullets[i].y > enemies[j].y-10 && bullets[i].y < enemies[j].y+10 )
        
            enemies[j].health-=bullets[i].dmg;
            if(enemies[j].health<=0)trEn.push_back(j);break;
        
    

子弹向量只是另一个类似于敌人向量的向量,但其中包含子弹。那个似乎不是问题。所有这些代码都运行良好,但在实际删除我的敌人向量中的项目时,程序有时会崩溃。

std::reverse( trEn.begin(), trEn.end() );
for ( unsigned int g = 0; g < trEn.size(); g++ ) 
    unsigned int atmp = trEn.at(g);
    if(atmp<=enemies.size()&&atmp>=0)enemies.erase(enemies.begin()+atmp,enemies.begin()+atmp+1);
 trEn.clear();

首先我反转int´s 的向量,使其从后向前。如果我不这样做,trEn[0] 之后的所有值都将无效。 这是让我崩溃的循环,但只是有时。我正在尝试做的是一个自上而下的射击游戏,似乎当很多东西应该同时被移除时,它就会崩溃。请帮我解决这个问题!

只要问我是不是不清楚还是有什么遗漏。

【问题讨论】:

【参考方案1】:

唯一看似显而易见的是:

if(atmp<=enemies.size() ...

你确定你不是指(atmp &lt; enemies.size())吗?否则你的代码

enemies.erase(enemies.begin()+atmp, ...

肯定会产生一些严重的问题。

【讨论】:

实际上 - 这可能应该是一个断言而不是一个条件,因为据我所知,atmp 永远不可能 >= 大于敌人的大小。 过于依赖其余代码,未显示。但是对于这个问题的背景,我同意 OP 可能已经考虑到了这一点。 如果我认为断言意味着如果 atmp > 敌人的大小是不可能的,程序应该将其作为错误捕获,我是对的吗?有时我是个新手…… 我在这里断言的意思是,在使用 if 语句时,有一个隐含的期望,即“if”的条件有时可能是错误的。但是,在我看来,它永远不应该。如果生成的代码需要“if”,那么它只是隐藏了一个缺陷。我会将其更改为“断言(!atmp > = enimies.size())”或者可能使用“if”,但如果不能立即死亡则抛出异常:“if(atmp => enimies.size()) throw SeriousErrorInCode ();". 顺便说一句,其他人对assert有不同的看法-checkout ***.com/questions/117171/…【参考方案2】:

您的第一个代码示例是两个嵌套循环 - 您迭代子弹,并为每个子弹迭代敌人,将敌人索引添加到 trEn 向量。是什么让你认为 trEn 的内容在那之后是按升序排序的?对于第一个项目符号,您可以添加索引 3,对于第二个索引 2。您甚至可以为不同的项目符号添加相同的索引。还是我错过了什么?

【讨论】:

啊,说得好,没想到。事实上,我刚刚意识到,当我向前面的敌人射击时,敌人部落中间的敌人可能会消失,这意味着无论如何顺序都搞砸了。因为它是一个整数向量,所以应该很容易排序。是否有一些标准功能来进行排序或我应该自己做? 我猜 std::sort 会做 :-) 它似乎有时仍然可以移除多个敌人,很明显这是因为向量中的重复条目。是否也有一些神奇的功能可以删除它们? 您可能想要使用 std::set。它是排序的,它的元素是独一无二的。

以上是关于从 for 循环崩溃中的向量中删除?的主要内容,如果未能解决你的问题,请参考以下文章

从向量中删除opencv rect对象

删除指针向量时遇到问题

iPhone托管对象删除崩溃

从 NSMutableArray 中删除 for 循环中的对象

从嵌套for循环中的指针集中删除项目

从 R 中的字符向量中删除引号