微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C++ 对象删除崩溃

如何解决C++ 对象删除崩溃

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

        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 是来自类 Projectiles 的对象向量。 成员函数 move 完美运行,函数 destroy 看起来像这样:

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

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

解决方法

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

话虽如此,您在遍历它的同时也在修改 player.projectiles,因此您的循环将至少在删除元素时 跳过元素,并且 甚至可能越界。您不得在调用 i 的迭代中增加 erase() 计数器,例如:

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() 返回一个迭代器到被擦除元素之后的下一个元素,所以让你的循环使用迭代器而不是索引,例如:

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

或者,您可以通过 erase-remove 使用 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,WIDTH); }
);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。