2013-06-28 60 views
-1

大部分時間我都對如何完成對stl對象的分配/取消分配感到困惑。例如:採取這個循環。如何在標準模板庫中完成對象的分配/取消分配

vector<vector<int>> example; 
for(//some conditions) { 
    vector<int>row; 
    for(//some conditions) { 
     row.push_back(k); //k is some int. 
    } 
    example.push_back(row); 
} 

在這種情況下,對象行發生了什麼情況。如果通過示例訪問,我仍然可以看到值,這意味着當我執行example.push_back(row)時,會創建一個新副本。我對麼。有沒有一種防止相同的好方法(如果我是正確的)。

任何人都可以提供參考,我可以閱讀如何在stl中處理分配/取消分配或避免此類內存複製問題(在大型應用程序的情況下)的最佳做法。

任何幫助表示讚賞。

+0

不是每一個'push_back'都會導致新的內存分配;如果容器已經有內存,它將使用它來構造一個新的對象。查找'std :: vector :: reserve'。 – legends2k

+2

在這個例子中,你可以做'example.push_back(std :: move(row));',因爲之後沒有任何東西使用'row'。 – aschepler

+0

事實是'std :: vector'在內部複製數據(有時它必須分配更多的內存來處理越來越多的元素)。你總是可以使用指針來減輕對象拷貝的開銷,但是記得在之後刪除它們(否則使用智能指針)。 – freitass

回答

3

當我做example.push_back(row)時創建一個新副本。我對麼。

是的。

,以防止有相同

爲什麼要阻止它的好辦法?這種行爲使vector簡單而安全。

標準庫容器具有值語義,因此它們會爲您添加的值添加一個副本,並管理這些值的生命週期,因此您無需擔心。

而且任何人都可以提供參考,我可以讀了如何分配/釋放在STL

處理你從未聽說過的搜索引擎?嘗試http://www.sgi.com/tech/stl/Allocators.html初學者。

或什麼是避免此類內存複製問題(在大型應用程序的情況下)的最佳實踐。

一般:忘了它。您通常不需要擔心,除非分析表明存在性能問題。

std::vector確實允許在其內存使用更細粒度的控制,看到http://www.sgi.com/tech/stl/Vector.html新成員部分和腳註獲取更多信息。

對於你的榜樣,您可以添加一個新行example容器然後直接添加int值是:

vector<vector<int>> example; 
for(/*some conditions*/) { 
    example.resize(example.size()+1); 
    vector<int>& row = example.back(); 
    for(/*some conditions*/) { 
     row.push_back(k); //k is some int. 
    } 
} 

更妙的是提前預約的載體足夠的能力:

vector<vector<int>> example; 
example.reserve(/* maximum expected size of vector */); 
for(/*some conditions*/) { 
    example.resize(example.size()+1); 
    vector<int>& row = example.back(); 
    for(/*some conditions*/) { 
     row.push_back(k); //k is some int. 
    } 
} 
+0

我想阻止它,因爲它更有效率。我不知道一個方法,我問了這個問題以確保。聽說過一個搜索引擎也使用它,但我要求給你資源來閱讀,以防有辦法避免它。我想你的答案表明沒有關於該主題的資源,因爲它不是那麼重要(「忘記它的一部分」)。至於使用'reserve()'。這是一個非常天真的啓發式,如果我知道大小之前,我會用新分配內存而不是使用stl(異常等可以處理)。無論如何感謝您的答案,這是部分有用的。:) –

+0

我給你的資源閱讀該主題,更仔細地閱讀答案。你最好不要讀像Josuttis這樣的好書,因爲它是一個廣泛的話題,需要一個好的作者來完整地解釋它 –

+0

另外我的答案顯示_exactly_如何避免'example.push_back(row)'創建一個新副本,它是你要求的。也許你需要更仔細地閱讀代碼。 –

0

所有stl實現必須遵守標準。

std::swap通常用於切換矢量的內容與另一個。這可以用來防止價值副本被採用,並且是實現效率的一個好方法,至少在C++ 11之前的版本中是這樣。 (在你的情況下,推回一個空的矢量,並與你創建的矢量交換)。

+2

或者推一個空向量並直接向它添加'int' –

+0

@Jonathan Wakely;是的,在這個角色中,因爲它是一個整數矢量,所以這是非常好的建議; +1有幫助。我的答案是在更大的數據類型的更一般的背景下閱讀。 – Bathsheba