【问题标题】:Storing iterators inside containers在容器中存储迭代器
【发布时间】:2009-07-16 12:09:54
【问题描述】:

我正在构建另一个应用程序将使用的 DLL。我想在从函数调用返回之前将某些数据的当前状态全局存储在 DLL 的内存中,以便在下次调用该函数时重用状态。

为此,我不得不保存一些迭代器。我正在使用 std::stack 来存储所有其他数据,但我不确定是否也可以使用迭代器来做到这一点。

将列表迭代器放在容器类中是否安全?如果没有,您能否建议一种方法来存储指向列表中元素的指针,以便我以后可以使用它?

我知道使用向量而不是列表来存储我的数据可以让我存储下标并非常轻松地重用它,但不幸的是我只能使用 std::list。

【问题讨论】:

    标签: c++ stl iterator


    【解决方案1】:

    仅当列表被销毁或“指向”元素从列表中删除时,列表的迭代器才会失效。

    【讨论】:

    • 只是一个疑问,如果我将迭代器存储在变量中的列表 的开头,然后我在第一个元素之前插入一个元素,那么如果我尊重我之前的迭代器,将它给了我里面存在的价值还是会失效?
    【解决方案2】:

    是的,它会正常工作的。

    由于关于这是列表迭代器的特殊质量的许多其他答案,我必须指出它适用于 any 迭代器,包括矢量迭代器。如果向量被修改,向量迭代器会失效这一事实与将迭代器存储在另一个容器中是否合法的问题几乎没有关系——它。当然,如果您执行任何使迭代器无效的操作,迭代器也会失效,但这与迭代器是否存储在堆栈(或任何其他数据结构)中无关。

    【讨论】:

      【解决方案3】:

      存储迭代器应该没问题,只要确保不要在列表的副本上使用它们——迭代器绑定到列表的一个实例,并且不能在副本上使用。

      也就是说,如果你这样做:

      std::list<int>::iterator it = myList.begin ();
      std::list<int> c = myList;
      
      c.insert (it, ...); // Error
      

      正如其他人所说:当然,您也不应该通过删除指向的元素来使迭代器无效。

      【讨论】:

        【解决方案4】:

        这可能是题外话,但只是一个提示......

        请注意,您的函数/数据结构对于读取操作可能是线程不安全的。有一种基本的线程安全性,其中读取操作不需要同步。如果您要存储调用者从您的结构中读取了多少数据,这将使整个概念线程不安全并且使用起来有点不自然。因为没有人认为读取是全状态操作。

        如果两个线程要调用它,它们要么需要同步调用,要么你的数据结构可能最终处于竞争状态。这种设计的问题是两个线程都必须能够访问一个公共的同步变量。

        我建议制作两个重载函数。两者都是无状态的,但其中一个应该接受提示迭代器,从哪里开始下一次读取/搜索/检索等。例如STL 中的分配器是如何实现的。您可以向分配器传递一个提示指针(默认为 0),以便它更快地找到新的内存块。

        问候,
        风向标

        【讨论】:

        • 感谢您的提示,ovanes。但是在我的情况下不会出现问题,因为每个线程的状态都存储在单独的位置。一次只有一个线程会从容器中读取。我不确定我是否完全理解重载函数的方式,我必须阅读有关分配器的内容,但也感谢您的建议。听起来很有趣
        【解决方案5】:

        存储列表的迭代器应该没问题。除非您从存储迭代器的列表中删除相同的元素,否则它不会失效。以下来自SGI 网站的引用:

        列表具有以下重要属性: 插入和拼接不 使迭代器无效以列出元素, 并且即使删除也只会无效 指向的迭代器 被移除的元素

        但是,请注意,存储迭代器的前一个和下一个元素可能会发生变化。但迭代器本身将保持有效。

        【讨论】:

        • 他没有说任何关于修改列表的事情,所以我一开始就看不到失效如何成为一个问题。
        【解决方案6】:

        同样的规则适用于存储在局部变量中的迭代器,就像存储在更长寿命的数据结构中一样:只要容器允许,它将保持有效。

        对于一个列表,这意味着:只要它指向的节点没有被删除,迭代器就保持有效。显然,当列表被破坏时,节点会被删除......

        【讨论】:

          猜你喜欢
          • 2013-06-06
          • 2022-06-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-25
          • 1970-01-01
          • 2020-12-12
          相关资源
          最近更新 更多