C++ 如何通过getter函数删除向量的元素? GetDstP()->xx语义,并在中间循环中擦除该项,因为擦除“向量< /代码>中的项无效其迭代器。

C++ 如何通过getter函数删除向量的元素? GetDstP()->xx语义,并在中间循环中擦除该项,因为擦除“向量< /代码>中的项无效其迭代器。,c++,singleton,sdl,state-machine,C++,Singleton,Sdl,State Machine,我需要移动的一些代码管理和删除我的敌人向量中的敌人,如下所示。因为我在类之外访问这些向量,所以我使用下面的getter函数。如果敌人离开屏幕,我将尝试删除他们。但是当敌人离开屏幕时,会引发以下未处理的异常: _最后一个是0xDDDD5。我们非常感谢能提供的任何帮助 for (int i = 0; i < (int)m_vEnemies.size(); i++) { m_vEnemies[i]->Update(); if (m_vEnemies

我需要移动的一些代码管理和删除我的敌人向量中的敌人,如下所示。因为我在类之外访问这些向量,所以我使用下面的getter函数。如果敌人离开屏幕,我将尝试删除他们。但是当敌人离开屏幕时,会引发以下未处理的异常: _最后一个是0xDDDD5。我们非常感谢能提供的任何帮助

for (int i = 0; i < (int)m_vEnemies.size(); i++)
    {
        m_vEnemies[i]->Update(); 
        if (m_vEnemies[i]->GetDstP()->x < -56)
        {
            delete m_vEnemies[i];
            m_vEnemies[i] = nullptr;

        }
    }
for(int i=0;i<(int)m_vEnemies.size();i++)
{
m_vEnemies[i]->Update();
如果(m_vEnemies[i]->GetDstP()->x<-56)
{
删除m_vEnemies[i];
m_vEnemies[i]=nullptr;
}
}
向量引擎::GetForeigns() { 返回m_vEnemies; } 对于(int i=0;i<(int)引擎::实例().getForeigns().size();i++) { 引擎::实例(); if(Engine::Instance().getForeigns()[i]->GetDstP()->x<-56) { 删除引擎::实例(); 引擎::实例(); } }
您正在删除由
m_vEnemies[i]
指向的对象,并将
m_vEnemies[i]
设置为
nullptr
,但下次迭代数组时,
nullptr
仍然存在,您将尝试取消对它的引用。您还需要从矢量中删除项目。使用迭代器从向量中删除项

但是,您不能仅使用标准<代码>(Auto It= V.Read),It!.V.Enter();It++代码>语义,并在中间循环中擦除该项,因为擦除“<代码>向量< /代码>中的项无效其迭代器。

诀窍是使用迭代器访问要删除的项

std::vector<T *>::iterator erase_iterator = v.begin() + i;
您还可以包括
算法
库,并使用
std::remove_if
函数<如果对容器的每个项目应用谓词,则代码>删除,如果满足条件,则将项目移动到容器的末尾(可能使其数据无效)。由于指针在移动到容器末尾后可能会失效,因此我们需要在移动之前(即从函子返回true之前)删除它

然后,容器在向量的开头包含所有有效元素,保留顺序,在结尾包含所有无效元素
remove_if
返回一个迭代器到无效元素开始的范围的开始。在调用
remove\u if
之后,应该在此虚拟开始迭代器和容器末尾之间的范围内调用
std::erase

#include <iostream>
#include <vector>
#include <algorithm>

void print_container_info(std::vector<int *>& container)
{
    std::cout << "Container size: " << container.size() << "\n";
    std::cout << "Container contents: ";
    for (auto& item : container)
    {
        std::cout << *item << " ";
    }
}

int main(int argc, char** argv)
{
    std::vector<int*> p_int_vec = { new int(3), new int(1), new int(2), new int(2), new int(3), new int(3), new int(2) };
    print_container_info(p_int_vec);
    std::cout << "\n\n";

    std::cout << "Removing all elements equal to 2 using for loop\n";
    auto dummy_begin = std::remove_if(p_int_vec.begin(), p_int_vec.end(),
        [](int* p_int) {
            if (*p_int == 2)
            {
                delete p_int;
                return true;
            }
            return false;
        });
    p_int_vec.erase(dummy_begin, p_int_vec.end());
    print_container_info(p_int_vec);
    std::cout << "\n\n";
}
#包括
#包括
#包括
无效打印容器信息(标准::矢量和容器)
{

std::请注意,当您删除此元素并将其设置为
nullptr
时,下次迭代
向量时,您需要确保处理
m_vEnemies
nullptr
的元素(您当前没有这样做)。当您使用调试器运行程序时,您看到了什么?这就是调试器的用途。如果您不知道如何使用调试器,这是一个很好的机会,可以学习如何使用调试器一次运行一行程序,监视所有变量及其值的变化,并分析程序的逻辑执行流。了解h使用调试器是每个C++开发人员所需的技能,没有例外。在调试器的帮助下,您应该能够快速找到您编写的所有和将来的程序中的所有bug,而不必向任何人求助。g my vector erase迭代器超出范围。我从您的帮助中编写的代码是if(Engine::Instance().GetForeigns()[I]->GetDstP()->x@eric描述要删除的元素的迭代器是
x.begin()+I
,而不是
x.begin()+i+i
。您添加了两次
i
,这最多可能超出范围,最坏可能会悄悄删除错误的元素。嗨,John,再次感谢您的帮助。我补充说,因为我仍然收到错误,向量擦除迭代器超出范围,而没有额外的+1。因此,如果(Engine::Instance().GetForeigns()[i]->GetDstP()->x您的for循环是什么样子的?我的for循环是这样的:for(int i=0;i<(int)Engine::Instance().GetForeigns().size();i++){}如果有区别,我的敌人会在计时器上生成
#include <iostream>
#include <vector>


void print_container_info(std::vector<int *>& container)
{
    std::cout << "Container size: " << container.size() << "\n";
    std::cout << "Container contents: ";
    for (auto& item : container)
    {
        std::cout << *item << " ";
    }
}

int main(int argc, char** argv)
{
    std::vector<int*> p_int_vec = { new int(3), new int(1), new int(2), new int(2), new int(3), new int(3), new int(2) };
    print_container_info(p_int_vec);
    std::cout << "\n\n";

    std::cout << "Removing all elements equal to 2 using for loop\n";
    for (std::size_t i = 0; i < p_int_vec.size(); i++) 
    {
        if (*p_int_vec[i] == 2)
        {
            auto erase_iterator = p_int_vec.begin() + i;
            delete p_int_vec[i];
            p_int_vec.erase(erase_iterator); //no need to set to nullptr, we're removing it from the container
            --i; // must decrement
        }
    }
    print_container_info(p_int_vec);
    std::cout << "\n\n";
}
#include <iostream>
#include <vector>
#include <algorithm>

void print_container_info(std::vector<int *>& container)
{
    std::cout << "Container size: " << container.size() << "\n";
    std::cout << "Container contents: ";
    for (auto& item : container)
    {
        std::cout << *item << " ";
    }
}

int main(int argc, char** argv)
{
    std::vector<int*> p_int_vec = { new int(3), new int(1), new int(2), new int(2), new int(3), new int(3), new int(2) };
    print_container_info(p_int_vec);
    std::cout << "\n\n";

    std::cout << "Removing all elements equal to 2 using for loop\n";
    auto dummy_begin = std::remove_if(p_int_vec.begin(), p_int_vec.end(),
        [](int* p_int) {
            if (*p_int == 2)
            {
                delete p_int;
                return true;
            }
            return false;
        });
    p_int_vec.erase(dummy_begin, p_int_vec.end());
    print_container_info(p_int_vec);
    std::cout << "\n\n";
}