在C ++中创建字符串HashMap到字符串向量的最佳方法是什么?

时间:2010-08-26 23:28:44

标签: c++

标准,不希望在整个地方创建对象的副本。 应该快速,内存效率高,不应该造成泄漏。 应该是线程安全的。

理想情况下,我想在HashMap中存储指向矢量的指针,但我担心内存泄漏。

这是最好的方式吗?

std::map<std::string, std::auto_ptr<std::vector<std::string> > > adjacencyMap;

7 个答案:

答案 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)

捆绑了很多问题......

  1. 哈希地图:std::unordered_mapstd::tr1::unordered_mapboost::unordered_map是哈希地图。它们是可靠的,但不是线程安全的(稍后再见)
  2. 性能:存储普通vector,你将避免内存泄漏,即将推出的C ++ 0x可能会被移动而不是复制< / em>因此你将同时具备性能和安全性......同时,在分析告诉你瓶颈在哪里之前,不要担心性能。
  3. 线程安全:拥有一个线程安全的容器几乎没用,因为你很可能想要线程安全的操作......
  4. 解释后一点:假设我有一个名为tbb::concurrent_hash_map的华丽container

    • 主题1 if (!container.empty())
    • 主题2 container.clear()
    • 主题1 { value = container.front(); } // Undefined behavior

    问题是线程安全容器不保证线程正确性。您仍然需要为您的操作明确锁定容器,因此容器锁定在您的锁中是毫无意义的。

    所以不要太担心找到线程安全的容器,STL没有任何东西的原因是它无论如何都是无用的,因为你想要的大部分操作是复合和需要锁定整个套件,而不是在每个套件之间释放。

答案 6 :(得分:0)

根据您的线程安全标准:在非平凡的情况下,没有STL容器可以保证线程安全。在某些情况下,您可以使用某些并发访问模式,但我怀疑您是否能够使用哈希映射。

如果这确实是您所需要的,那么您将需要一个线程安全的哈希映射类。英特尔Threading Building Blocks有一个concurrent_hash_map类IIRC,这对我来说似乎是最明显的选择,虽然我确信还有其他选择。

虽然注意到这当然不会使你的向量线程安全,只有包含hashmap;如果您也需要,TBB也有concurrent_vector