C++对象删除崩溃

C++ object deletion crashing

我试图包含所有可能导致这些问题的必要代码。 程序第二次崩溃这段代码是运行:

        for (int i = 0; i < player.projectiles.size(); i++)
        {
            bool temp = player.projectiles[i].move(begin, WIDTH);
            if (temp == true)
            {
                player.projectiles[i].destroy();
                player.projectiles.erase(player.projectiles.begin() + i);
            }
        }

Player.projectiles 是来自 class 射弹的对象向量。 成员函数 move 完美运行,函数 destroy 如下所示:

void Projectile::destroy()
{
    delete this;
}

第一次循环 运行 一切正常,但第二次我的程序崩溃了,我不明白为什么。我怀疑这与删除对象有关。非常感谢任何帮助。

您没有在 vector 中存储 Projectile* 指针 ,您存储的是实际 Projectile 对象(您的循环正在使用 operator. 而不是 operator-> 访问 Projectile class 的成员这一事实就证明了这一点)。因此,对这些对象中的任何一个调用 destroy() 绝对是错误的做法,因为您不拥有该内存! vector 会,因此当对象从 vector 中移除时,会为您销毁每个对象,包括当 vector 被清除或销毁自身时。

话虽这么说,你也在修改 player.projectiles 的同时遍历它,所以你的循环至少会 跳过元素 因为元素正在被删除,并且 甚至可以 出界。您不得在调用 erase() 的迭代中增加 i 计数器,例如:

for (size_t i = 0; i < player.projectiles.size(); )
{
    if (player.projectiles[i].move(begin, WIDTH))
        player.projectiles.erase(player.projectiles.begin() + i);
    else
        ++i;
}

或者,vector::erase() returns 一个 迭代器 到被擦除元素之后的下一个元素,所以让你的循环使用迭代器而不是索引,例如:

for(auto iter = player.projectiles.begin(); iter != player.projectiles.end(); )
{
    if (iter->move(begin, WIDTH))
        iter = player.projectiles.erase(iter);
    else
        ++iter;
}

或者,您可以使用 erase-remove idiom via std::remove_if() 替换整个循环,例如:

#include <algorithm>

player.projectiles.erase(
    std::remove_if(player.projectiles.begin(), player.projectiles.end(),
        [=](auto &projectile) { return projectile.move(begin, WIDTH); }
    ),
    player.projectiles.end()
);

或者,在 C++20 中 std::erase_if()

std::erase_if(
    player.projectiles,
    [=](auto &projectile) { return projectile.move(begin, WIDTH); }
);