簡體   English   中英

通過在C ++中刪除向量中的向量來釋放內存

[英]Freeing up memory by deleting a vector in a vector in C++

我有一個向量載體,我希望從內存中完全刪除myvec [i],釋放空間,依此類推。 .erase或.clear會為我完成這項工作嗎? 如果沒有,我該怎么辦?

完全刪除向量

如果要完全刪除myvec中索引i處的向量,以使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向量少它。

清空但保留向量

但是,如果您不想從myvec刪除第i個矢量,而只想在將空矢量保持在原位的同時將其完全清空,則可以使用多種方法。

基本方法

常用的一種技術是將要清空的向量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_fitshring_to_fit執行的操作。)這是一個非常昂貴的操作,至少在刪除單個元素方面,卻幾乎沒有實際收益。 如果要擦除大量元素,則在所有擦除之后都值得考慮。

最后,如果要擦除所有元素,則myvec.erase()與每個元素上的myvec.clear()完全相同,並具有上述相同的注意事項。 在這種情況下,創建一個空向量並交換是一個更好的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM