準則,不要在整個地方創建對象的副本。 應該是快速,高效的內存,不應該造成泄漏。 應該是線程安全的。在C++中創建字符串向量向量的HashMap的最佳方式是什麼?
理想情況下,我想存儲指向HashMap中向量的指針,但我擔心這種內存泄漏。
這是最好的方法嗎?
std::map<std::string, std::auto_ptr<std::vector<std::string> > > adjacencyMap;
準則,不要在整個地方創建對象的副本。 應該是快速,高效的內存,不應該造成泄漏。 應該是線程安全的。在C++中創建字符串向量向量的HashMap的最佳方式是什麼?
理想情況下,我想存儲指向HashMap中向量的指針,但我擔心這種內存泄漏。
這是最好的方法嗎?
std::map<std::string, std::auto_ptr<std::vector<std::string> > > adjacencyMap;
您被禁止在任何標準容器中存儲auto_ptr
。 §23.1/ 3:「存儲在這些組件中的對象類型必須滿足CopyConstructible 類型(20.1.3)的要求以及可分配類型的附加要求。」 std::auto_ptr
不符合該要求。
這是非常聰明的做法。
我只能提出的建議是避免將auto_ptr放入STL容器中。 http://www.devx.com/tips/Tip/13606
如果您使用shared_ptr,而不是一切都應該正常工作。 http://beta.boost.org/doc/libs/1_40_0/libs/smart_ptr/shared_ptr.htm
如果使用C++ 0x,請使用unique_ptr
。如果不是,請使用boost::shared_ptr
。
C++ 0x何時可用?建議使用它的生產代碼? – user855 2010-08-27 03:00:49
一個std ::地圖<>不作爲的hash_map實現,但作爲一個紅黑樹(見http://en.wikipedia.org/wiki/Map_(C%2B%2B))
您可以的C++ 0x編譯器或std使用std :: unordered_map <> :: tr1 :: unordered_map <>用於非C++ 0x編譯器。
Boost也有它的version。
......怎麼
map<string, vector<string> >
請注意,地圖是在相當特殊不像說Vector中的元素映射大小調整期間從不復制或在其他元素被插入或刪除。出於這個原因,不需要使用指針來防止不必要的深度拷貝。
從http://www.sgi.com/tech/stl/Map.html:
「地圖有插入一個新元素到地圖並不能否定指向現有元素的迭代從地圖刪除的元素也並不能否定任何迭代器,除了重要的特性,當然,對於實際上指向正在被擦除的元素的迭代器。「
當然,如果你不在原地構建一個值,並且如果你由於某種原因需要複製它,但是往往很容易做到一切都很容易原地的,或許用輔助翼:
vector<string>& this_one = my_map[my_key];
// work on this_one
在你的線程安全標準:STL容器都不在不平凡的情況下保證線程安全的。在某些情況下,您可以避開某些併發訪問模式,但我懷疑您可以使用散列映射進行工作。
如果這真的是你需要的,那麼你將需要一個線程安全的哈希映射類。英特爾的Threading Building Blocks有一個concurrent_hash_map
class IIRC,這對我來說似乎是最明顯的選擇,但我確信還有其他的選項。
雖然注意這當然不會使你的向量線程安全,只有包含hashmap;如果您也需要,TBB也有concurrent_vector
。
這麼多的問題...
std::unordered_map
,std::tr1::unordered_map
或boost::unordered_map
是哈希映射。他們是可靠的,但不是線程安全的(見稍後)vector
,你會避免內存泄漏,與即將推出的C++ 0x很可能,他們將移動周圍,而不是複製,因此您將同時具備性能和安全性......同時,在性能分析告訴您哪裏存在瓶頸之前,不要擔心性能。解釋後一點:假設我有一個宏偉的tbb::concurrent_hash_map
命名container
。
if (!container.empty())
container.clear()
{ value = container.front(); } // Undefined behavior
的問題是線程安全的容器不保證線程正確性。你仍然需要爲你的操作顯式地鎖定容器,因此容器鎖定在你的鎖中將是毫無意義的。
所以不要太在乎尋找線程安全的容器,很理性的STL沒有任何的是,它幾乎是無用的呢,因爲你最想要的操作都是複合,並要求鎖爲整個套件舉行,而不是在每個人之間發佈。
您的評論只是讓我意識到爲什麼我從來不想要線程安全的容器(或者爲什麼他們總是在我用Java編程的時候出錯) – 2010-08-28 19:38:44
請記住,std :: map不是一個哈希映射,而是一個有序映射(大多數編譯器將它實現爲二叉樹)。 哈希映射(std :: unordered_map)將成爲下一版本標準的一部分。您的編譯器可能已經包含它。如果不是,Boost有一個。 – 2010-08-26 23:39:54