2012-02-15 55 views
2

當我用「擦除」刪除矢量中的元素時,則沒有清除內存。例如,我製作了一個尺寸爲2000的矢量。創建之後,程序使用1.5 MB內存。當我進行擦除調用時,什麼都不會被清除。所有的元素都消失了。但他們仍在記憶中。如何刪除矢量中的元素。 (擦除將不起作用)

例如:

#include <iostream> 
#include <vector> 

using namespace std; 


int main() 
{ 
    //Makes a vector of 2000 items 
    vector<int> test(200000); 

    //Pause for test purpose 
    system("pause"); 

    //erase all elements 
    test.erase(test.begin(),test.end()); 

    //Pause for test purpose 
    system("pause"); 

    return false; 
} 

尺寸返回0。但是,這一過程仍然使用的存儲器1,5MB。

+2

你如何測量進程正在使用的內存? – 2012-02-15 07:52:27

+0

也許你應該閱讀: http://stackoverflow.com/questions/586634/shrinking-a-vector 希望它能幫助。 – 2012-02-15 07:54:40

回答

8

erase不釋放內存。標準要求代碼test.capacity() >= 200000之後。使用

test.shrink_to_fit(); // in C++11 
vector<int>(test).swap(test); // in C++03 

減少向量的容量。請注意,這仍然不能保證系統其餘部分的內存使用量會下降。一般來說,過程堆不能縮小。

+0

將'test'傳遞給構造函數有什麼意義?爲什麼不只是用空載體交換'temp'? – sharptooth 2012-02-15 07:56:40

+0

@sharptooth:發佈的代碼更通用 - 即使您只想刪除某些元素,也可以工作。 – ybungalobill 2012-02-15 07:58:05

0

你可能喜歡這種方式測試:

簡單的目的
int main() 
{ 
    //Makes a vector of 2000 items 
    { 
     vector<int> test(200000); 

     //Pause for test purpose 
     system("pause"); 

     //erase all elements 
     test.erase(test.begin(),test.end()); 

     // Call erase or not, but destructor will be called here - freeing all memory 
    } 

    //Pause for test purpose 
    system("pause"); 

    return false; 
} 

vector.erase deons't釋放內存 - 可能分配給它的,而不是重新分配用於將來的請求的內存可重用性。

+0

矢量用於整個過程。所以我不能在我的情況下使用這個。 – Laurence 2012-02-15 08:05:58

0

當進程終止時,內存回收你的情況。所以,不需要擦除矢量。
如果要繼續在循環中使用該向量,請考慮使用清除向量內容的clear()
如果矢量用在一個對象中,那麼一旦對象被銷燬,矢量也被銷燬。
但是,如果向量包含指針,那麼你必須明確地刪除它們。

+0

我想在活着時清理矢量。它在整個過程中使用。所以我不能在我的情況下使用這個。 – Laurence 2012-02-15 08:06:58

+0

正如其他人所說的swap()技巧或shrink_to_fit()將清理向量。內存將被回收或不依賴於庫或編譯器的實現。由於優化原因,他們通常不會這樣做。 – Jagannath 2012-02-15 09:38:34

11

有兩個原因的過程中保持記憶:

  • std::vector時,它的增長只會重新分配內存,而不是當它收縮。
  • 釋放的內存通常會被進程保留以供重用。

在C++ 11,載體具有shrink_to_fit成員函數,這將要求矢量如果可能的話,以減少所分配的存儲器的量。儘管如此,不能保證它會這樣做。在C++ 03,或者如果你想保證多餘的內存被釋放,你可以使用一個新分配的一個交換載體的絕招:

std::vector<int>(test).swap(test); 

,或者如果你想徹底清除它:

std::vector<int>().swap(test); 

這個技巧將分配的內存的所有權移動到臨時向量;在表達式的末尾,該向量被破壞,釋放內存。

內存是否從流程中釋放完全取決於您的圖書館如何管理免費商店。通常,小分配(可能高達幾兆字節)由堆處理 - 該進程從系統請求大塊內存,並將其分成小塊。除非所有小塊已經被釋放,否則塊不能被釋放,並且即使那樣,許多實現也不會釋放它們。

可以從系統直接請求較大的分配,在這種情況下,一旦釋放,它們將被釋放。

所以,你可以得到你所期望的代碼是這樣的效果:

// A few gigabytes will probably be allocated directly. 
// You'll have to reduce this on a 32-bit system, or if there's not enough memory 
std::vector<int> test(1000000000) 

// Use the "swap trick" to ensure the memory is deallocated. 
std::vector<int>().swap(test); 

但也不能保證,即使這將釋放從進程的內存;內存分配的細節不是由標準規定的,而是由編譯器/庫實現決定的。