标准,不希望在整个地方创建对象的副本。 应该快速,内存效率高,不应该造成泄漏。 应该是线程安全的。
理想情况下,我想在HashMap中存储指向矢量的指针,但我担心内存泄漏。
这是最好的方式吗?
std::map<std::string, std::auto_ptr<std::vector<std::string> > > adjacencyMap;
答案 0 :(得分:5)
您被禁止在任何标准容器中存储auto_ptr
。 §23.1/ 3:“存储在这些组件中的对象类型必须符合CopyConstructible的要求
类型(20.1.3),以及可分配类型的附加要求。“std::auto_ptr
不符合该要求。
答案 1 :(得分:4)
std :: map&lt;&gt;未实现为hash_map,而是实现为红黑树(请参阅http://en.wikipedia.org/wiki/Map_(C%2B%2B))
您可以使用std :: unordered_map&lt;&gt;对于c ++ 0x编译器或std :: tr1 :: unordered_map&lt;&gt;对于非c ++ 0x编译器。
Boost也有version。
答案 2 :(得分:1)
这是非常聪明的做法。
我可以提供的唯一建议是不要将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
答案 3 :(得分:1)
如果使用C ++ 0x,请使用unique_ptr
。如果没有,请使用boost::shared_ptr
。
答案 4 :(得分:1)
怎么样......
map<string, vector<string> >
请注意,地图非常特别,因为与矢量不同,在地图大小调整期间或插入或删除其他元素时,不会复制元素。因此,不需要使用指针来防止不必要的深层复制。
来自http://www.sgi.com/tech/stl/Map.html:
“Map具有以下重要特性:将新元素插入到映射中不会使指向现有元素的迭代器无效。从映射中删除元素也不会使任何迭代器无效,当然,除非实际指向的迭代器到正在删除的元素。“
当然,如果你没有就地构建一个值,可能会有一个深层复制将值复制到地图中,如果由于某种原因需要将其复制出来,但通常很容易做到-place,也许是帮手ala:
vector<string>& this_one = my_map[my_key];
// work on this_one
答案 5 :(得分:1)
捆绑了很多问题......
std::unordered_map
,std::tr1::unordered_map
或boost::unordered_map
是哈希地图。它们是可靠的,但不是线程安全的(稍后再见)vector
,你将避免内存泄漏,即将推出的C ++ 0x可能会被移动而不是复制< / em>因此你将同时具备性能和安全性......同时,在分析告诉你瓶颈在哪里之前,不要担心性能。解释后一点:假设我有一个名为tbb::concurrent_hash_map
的华丽container
。
if (!container.empty())
container.clear()
{ value = container.front(); } // Undefined behavior
问题是线程安全容器不保证线程正确性。您仍然需要为您的操作明确锁定容器,因此容器锁定在您的锁中是毫无意义的。
所以不要太担心找到线程安全的容器,STL没有任何东西的原因是它无论如何都是无用的,因为你想要的大部分操作是复合和需要锁定整个套件,而不是在每个套件之间释放。
答案 6 :(得分:0)
根据您的线程安全标准:在非平凡的情况下,没有STL容器可以保证线程安全。在某些情况下,您可以使用某些并发访问模式,但我怀疑您是否能够使用哈希映射。
如果这确实是您所需要的,那么您将需要一个线程安全的哈希映射类。英特尔Threading Building Blocks有一个concurrent_hash_map
类IIRC,这对我来说似乎是最明显的选择,虽然我确信还有其他选择。
虽然注意到这当然不会使你的向量线程安全,只有包含hashmap;如果您也需要,TBB也有concurrent_vector
。