【问题标题】:Deleting from vector in for loop crashes?从 for 循环崩溃中的向量中删除?
【发布时间】: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] 之后的所有值都将无效。 这是让我崩溃的循环,但只是有时。我正在尝试做的是一个自上而下的射击游戏,似乎当很多东西应该同时被移除时,它就会崩溃。请帮我解决这个问题!

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

【问题讨论】:

    标签: c++ loops for-loop memory-management vector


    【解决方案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 stackoverflow.com/questions/117171/…
    【解决方案2】:

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

    【讨论】:

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