类型<stuff *> </stuff *>的空向量

时间:2011-01-18 00:49:05

标签: c++

我有一个填充了对象的向量:

std::vector<Stuff*> stuffVector;

我正在尝试使用清理功能删除它的所有元素

void CleanUp()
{
    for (std::vector<Stuff*>::size_type i = 0 ; i < stuffVector.size() ; i++)
    {
        stuffVector.erase(stuffVector.begin()+i);
    }
    cout << stuffVector.size() << endl;
    if (stuffVector.size() == 0) cout << "Vector Emptied" << endl;
}

这总是向量报告,但是矢量中有很多对象的大小,实际上似乎根本没有删除任何东西。这很奇怪,因为类似的函数在别处可以从向量中删除特定对象:

void DestroyStuff()
{
    if (stuffVector.size() > 1)
    {
        for (std::vector<Stuff*>::size_type i = 0 ; i < stuffVector.size() ; i++ )
        {
            if(stuffVector[i]->CanDestroy())
            {
                stuffVector.erase (stuffVector.begin()+i);
            }
        }
    }
}

以上工作正常,但CleanUp()没有。为什么会发生这种情况?

5 个答案:

答案 0 :(得分:2)

擦除元素时,矢量的大小会发生变化。因此,在erase()i++的某些迭代中,您的循环正在跳过元素。

此外,要删除vector clear()函数的每个元素,都很有用。此外,循环遍历向量中所有元素的标准方法是使用迭代器。您的代码应如下所示:

void CleanUp()
{
    for (std::vector<Stuff*>::iterator it = stuffVector.begin() ; it != stuffVector.end() ; it++)
    {
        /* .. do something to each element to prepare it for removal */
        delete *it;         // clean up resources?
    }
    stuffVector.clear();
    cout << stuffVector.size() << endl;
    if (stuffVector.size() == 0) cout << "Vector Emptied" << endl;
}

void DestroyStuff()
{

    for (std::vector<Stuff*>::iterator it = stuffVector.begin() ; it != stuffVector.end() ; /*done inline*/)
    {
        if((*it)->CanDestroy())
        {
            it = stuffVector.erase(it);
        }
        else
            ++it;
    }
}

这个循环有效,因为erase()将迭代器返回到列表中的下一个元素。

答案 1 :(得分:1)

stuffvector.clear();

(min.length bah!)

答案 2 :(得分:0)

这是错误的:

for (std::vector<Stuff*>::size_type i = 0 ; i < stuffVector.size() ; i++)
{
    stuffVector.erase(stuffVector.begin()+i);
}

想象一下,向量中包含元素0, 1, 2, 3, 4。在第一次擦除(i==0)之后,它将是1, 2, 3, 4。使用i==1进行的第二次删除会将其呈现为1, 3, 4,最后,它将最终为1, 3

清除矢量的最佳选择是

stuffVector.clear()

,如果这不合适:

stuffVector.swap(std::vector<Stuff*>());

while(!stuffVector.empty()) stuffVector.pop_back();

stuffVector.erase(stuffVector.begin(), stuffVector.end());

删除矢量内容的其他方法留给读者练习:)

如果你想在清除它们之前用元素做其他事情(...就像删除指针指向的对象一样)我建议单独执行此操作,然后将矢量清除为单独的操作。或者使用空向量进行交换,并使用交换的向量执行任何操作。

答案 3 :(得分:0)

您的CleanUp()问题是vector :: erase()不会调用delete来释放指针或对象析构函数。它只会丢弃指针并泄漏内存。

答案 4 :(得分:0)

在itertaor上调用erase将使迭代器无效

 stuffVector.erase(stuffVector.begin()+i);

后面跟着for循环

 i++

删除后的指针甚至可能无法读取或复制。销毁使迭代器无效 以下可能会有所帮助

for(it = Entities.begin(); it != Entities.end();)
{
   if(...) //Conditional deletion
   {
       delete * it;
        it = Entities.erase(it);
   }
    else
    {
        it++;
     }
}