0

我有一个向量向量,我希望从内存中完全删除 myvec[i],释放房间,等等。.erase 或 .clear 会为我完成这项工作吗?如果没有,我该怎么办?

4

2 回答 2

4

完全删除向量

如果你想完全删除你的索引处的向量imyvec这样它就myvec[i]不再存在并且myvec.size()比以前少一个,你应该这样做:

myvec.erase (myvec.begin() + i); // Note that this only works on vectors

这将完全释放所有拥有的内存,myvec[i]并将其后的所有元素(myvec[i + 1]myvec[i + 2]等)移回一个位置,以便myvec其中少一个向量。

清空但保留向量

但是,如果您不想从 中删除第ith 个向量myvec,而只想完全清空它,同时保持空向量不变,则可以使用多种方法。

基本方法

一种常用的技术是使用swap新的完全空的向量来清空要清空的向量,如下所示:

// suppose the type of your vectors is vector<int>
vector<int>().swap (myvec[i]);

保证释放所有内存myvec[i],它很快并且不会分配任何新的堆内存或任何东西。

使用它是因为该方法clear不提供这样的保证。如果你clear是向量,它总是将其大小设置为零并破坏所有元素,但它可能不会(取决于实现)实际上释放内存。

在 C++11 中,你可以通过两个函数调用来做你想做的事:(感谢有用的评论)

myvec[i].clear();
myvec[i].shrink_to_fit();

概括

您可以编写一个适用于大多数(可能是所有)STL 容器等的小函数:

template <typename T>
void Eviscerate (T & x)
{
    T().swap (x);
}

你像这样使用它:

Eviscerate (myvec[i]);

这显然更干净,更易读,更不用说更通用了。

在 C++11 中,您还可以使用decltype编写通用解决方案(独立于容器和元素的类型),但它非常难看,我只是为了完整起见将其放在这里:

// You should include <utility> for std::remove_reference
typename std::remove_reference<decltype(myvec[i])>::type().swap(myvec[i]);

我推荐的方法是Eviscerate上面的函数。

于 2013-06-16T08:12:18.350 回答
1

myvec.erase( myvec.begin() + i )myvec[i] 完全删除,调用其析构函数,并释放其所有动态分配的内存。它不会减少myvec:直接使用的内存,myvec.size()将减少 1,但myvec.capacity()将保持不变。为了去除这最后的残留物,C++11 有myvec.shrink_to_fit(),它可能会去除它;否则,您必须制作 的完整副本myvec,然后将其换入:

void
shrink_to_fit( MyVecType& target )
{
    MyVecType tmp( target.begin(), target.end() );
    target.swap( tmp );
}

(这基本上就是幕后shring_to_fit要做的事情。)这是一个非常昂贵的操作,几乎没有真正的收益,至少在删除单个元素方面;如果您要擦除大量元素,则在所有擦除之后可能值得考虑。

最后,如果要擦除所有元素, myvec.clear()则与对每个元素完全相同myvec.erase(),具有与上述相同的注意事项。在这种情况下,创建一个空向量并进行交换是更好的解决方案。

于 2013-06-16T09:32:57.843 回答