通过在C ++中删除向量中的向量来释放内存

时间:2013-06-16 08:06:03

标签: c++ vector

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

2 个答案:

答案 0 :(得分:4)

完全删除矢量

如果您要完全删除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将减少一个向量。

清空但保留矢量

但是,如果您不想从myvec中移除swap向量,并且您只想在保持空向量到位的同时完全清空它,则有几种方法你可以使用。

基本方法

常用的一种技术是// suppose the type of your vectors is vector<int> vector<int>().swap (myvec[i]); 要用新的完全空的向量清空的向量,如下所示:

myvec[i]

保证可以释放clear中的所有内存,速度很快,并且它不会分配任何新的堆内存或任何内容。

使用此方法是因为方法clear不提供此类保证。如果你myvec[i].clear(); myvec[i].shrink_to_fit(); 向量,它总是将其大小设置为零并破坏所有元素,但它可能不会(取决于实现)实际释放内存。

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

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

概括

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

Eviscerate (myvec[i]);
你使用的

decltype

这显然更清晰,更具可读性,更不用说更通用了。

在C ++ 11中,您还可以使用// You should include <utility> for std::remove_reference typename std::remove_reference<decltype(myvec[i])>::type().swap(myvec[i]); 编写通用解决方案(独立于容器和元素的类型),但它非常难看,我只是把它放在这里完整性:

Eviscerate

我推荐的方法是上面的{{1}}函数。

答案 1 :(得分:1)

myvec.erase( myvec.begin() + i )将删除myvec[i] 完全,调用它的析构函数,释放所有它 动态分配内存。它将减少内存 由myvec直接使用:myvec.size()将减少一个, 但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()完全相同 元素,与上述相同的考虑因素。在这 case,创建一个空向量和交换是一个更好的 溶液