我有一个向量向量,我希望从内存中完全删除 myvec[i],释放房间,等等。.erase 或 .clear 会为我完成这项工作吗?如果没有,我该怎么办?
2 回答
完全删除向量
如果你想完全删除你的索引处的向量i
,myvec
这样它就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
其中少一个向量。
清空但保留向量
但是,如果您不想从 中删除第i
th 个向量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
上面的函数。
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()
,具有与上述相同的注意事项。在这种情况下,创建一个空向量并进行交换是更好的解决方案。