2008-11-25 98 views
5

的保留存儲器我有一個向量,其具有1000「節點」更改C++矢量

if(count + 1 > m_listItems.capacity()) 
    m_listItems.reserve(count + 100); 

問題是我還清楚它,當我關於重新填充它。

m_listItems.clear(); 

容量不變。 我使用了resize(1);但這似乎並沒有改變能力。 那麼如何改變儲備?

+0

您的系統內存不足?像這樣保留意味着向它添加n個項目使用O(n^2)時間並且最多有n + 100個對象值空間加上舍入誤差。讓這個向量擴展本身就是更少的代碼,O(n)時間,並且在大多數實現中最多使用2 * n空間加四捨五入。 – 2008-11-26 03:03:26

+0

我的系統在內存上很短(嵌入)..代碼實際上只是我想要實現的一個例子。大多數情況下,我從「表格」中獲得1000個條目塊,因此在相同頻率下調整大小是有意義的。 CLEANUP是我最關心的問題。 – baash05 2008-11-26 04:38:20

回答

20
vector<Item>(m_listItems).swap(m_listItems); 

將再度萎縮m_listItemshttp://www.gotw.ca/gotw/054.htm(香草薩特)

如果你想用空載體反正清除它,掉期:

vector<Item>().swap(m_listItems); 

這當然是辦法更高效。 (需要注意的是basicially交換向量;只是交換兩個指針真的沒什麼費時的事情)

+2

值得指出的是,雖然swap()非常便宜,但在第一種情況下構造m_listItems的臨時副本將需要複製向量中的每個元素。因此,完全清除矢量(將容量設置爲0)很便宜。否則縮小它不是。 – jalf 2008-11-26 13:17:36

+1

確實。但是如果向量本身具有一個shrink()函數,那麼該序列本質上是相同的。無論如何都需要重新分配:/ – 2008-11-26 13:33:41

1

你可以試試這個技術從here

std::vector<int> v; 
// ... fill v with stuff... 
std::vector<int>().swap(v); 
1

可以具有所期望的能力的新矢量swap它。

vector<int> tmp; 
old.swap(tmp); 
1

據我所知,你不能重新分配一個向量到一個較低的能力比以往任何時候都;你只能將它分配得更大。這有很好的理由;其中之一是重新分配過程的計算量非常大。如果你真的需要一個更小的向量,請釋放舊向量並創建一個更小的向量。這實際上比矢量實際調整尺寸更小的計算要簡單得多。

2

您可以把矢量正如其他人的建議,並在http://www.gotw.ca/gotw/054.htm描述,但要知道,這是不是免費,您要執行的每一個元素的副本,因爲載體必須分配一個新的,更小,大量的內存,並複製所有的舊內容。 (交換操作基本上是免費的,但你和一個臨時與原矢量數據的副本,這是免費初始化交換)

如果你事先知道的載體有多大,你應該分配開始與大小合適,所以不會進行調整是必要的:

std::vector<foo> v(1000); // Create a vector with capacity for 1000 elements 

而如果你事先不知道的能力,它爲什麼重要是否浪費一點空間?將每個元素複製到一個新的更小的向量(這是std :: vector(v).swap(v)將執行的操作)是否值得花費時間,只是爲了節省幾千字節的內存?同樣,當你清除矢量時,如果你打算重新填充它無論如何,將其容量設置爲零似乎是一個令人印象深刻的浪費時間。

編輯

baash05:如果你有百萬項目 的10兆內存。你會說 減少的開銷量是 重要嗎?

號調整大小的矢量需要內存,是暫時的,所以如果你的內存限制,這可能會破壞你的應用程序。 (你必須有內存中的原始矢量,的臨時,之前,你可以交換它們,所以你最終使用多達兩倍的RAM在那一點)。之後,您可能會節省少量的內存(最高可達幾MB),但這並不重要,因爲向量中的多餘容量永遠不會被訪問,所以它會被推送到頁面文件,所以不會首先計入你的內存限制。

如果您有1000000個項目,那麼您應該首先將矢量初始化爲的正確尺寸

如果你不能這樣做,那麼你通常最好離開容量單獨。特別是因爲你表示要重新填充矢量,所以你應該重新使用已經分配的容量,而不是不斷地分配,重新分配,複製和釋放所有內容。

你有兩種可能的情況。要麼你知道你需要存儲多少元素,要麼你不知道。如果你知道,那麼你可以首先創建正確大小的矢量,所以你永遠不需要調整它的大小,或者你不知道,然後你也可以保持多餘的容量,所以至少它當您重新填充矢量時,不必調整向上的大小。