【问题标题】:Pointers to elements of STL containers指向 STL 容器元素的指针
【发布时间】:2011-07-08 02:47:10
【问题描述】:

给定一个非连续的 STL 容器(你也可以考虑 boost::unordered_mapboost::multi_index_container),如果没有元素被删除,是否保证容器内元素的内存地址永远不会改变,(但可以添加新的)?

例如

class ABC { };
//
//...
//
std::list<ABC> abclist;
ABC abc;
abclist.insert(abc);
ABC * abc_ptr = &(*abclist.begin());

换句话说,如果我不从abc_list 中删除abc,那么在整个执行过程中abc_ptr 将被指向abc

我问这个是因为我要在 C++/Cli 中包装类 ABC,所以我需要指向包装类中的 ABC 实例的指针。 ABC 是一个简单的类,我希望容器来处理内存。如果答案是否定的,那么我将使用std::list&lt;ABC*&gt;

【问题讨论】:

    标签: c++ pointers stl memory-address


    【解决方案1】:

    我认为最好使用std::list &lt;shared_ptr &lt;ABC&gt; &gt; 而不是传递指针。 委派内存管理是一种很好的做法(参见 scott meyers Effective c++)

    这有很多好处:

    • 您可以分享和传递它们,而无需担心释放它们
    • 指针的垃圾收集
    • 你一开始就没有传递指针

    【讨论】:

    • 问题中的代码不是手动处理内存管理。对象生命周期由容器管理。请注意,所涉及的唯一指针是容器处理的对象的引用
    • 您错过了这里的重点:OP 需要一个指针(用于外部接口),并且他不执行手动内存管理...您的解决方案确实提供了任何好处。
    • 这与我的问题高度无关。不管有没有共享指针,我问一个元素的内存地址是否改变。
    【解决方案2】:

    std::liststd::setstd::map 保证在添加甚至删除新元素时迭代器(包括简单指针)不会失效。

    【讨论】:

    • OP 指定了一个不连续的容器,所以 vector 不在运行中。另外,“See”之后应该有什么东西吗?
    • 并且deque 保证它可以在末端添加元素,这对于这种用途来说可能已经足够了。
    【解决方案3】:

    C++ 标准对引用/迭代器的有效性提出了严格的规定。对于每个容器,每个方法都记录了哪些元素可以被移动(使引用和迭代器无效)。

    基于节点的容器:listmapsetmultimapmultiset 保证只要元素没有从容器中删除,对元素的引用和迭代器将保持有效。

    因此,您的用例是使用list 进行存储的极端情况之一,因为列表提供了失效保证。

    【讨论】:

      【解决方案4】:

      正如 Armen 提到的,std::list、std::set 和 std::map 保证只会使移除的迭代器无效。在 boost::unodered_map 的情况下,修饰符确实可能使迭代器无效。

      http://www.boost.org/doc/libs/1_38_0/doc/html/boost/unordered_map.html

      【讨论】:

      • 感谢您的链接。是的,根据文档,修饰符确实可能使迭代器无效,它还说我需要知道的Pointers and references to elements are never invalidated.boost::multi_index::hashed_unique 索引也像 boost::unordered_map 一样实现。
      猜你喜欢
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-11
      • 1970-01-01
      • 2011-03-12
      相关资源
      最近更新 更多