代码之家  ›  专栏  ›  技术社区  ›  Pillsy

指向容器中元素的指针

  •  4
  • Pillsy  · 技术社区  · 16 年前

    假设我有一个物体:

    struct Foo 
    {
        int bar_;
        Foo(int bar) bar_(bar) {}
    };
    

    我有一个STL容器 Foo S,也许是向量,我取

    // Elsewhere...
    
    vector<Foo> vec;
    
    vec.push_back(Foo(4));
    
    int *p = &(vec[0].bar_)
    

    这是个糟糕的主意,对吧?

    原因是 vector 将其元素存储在某个动态分配的数组中,最终,如果添加足够的元素,它将不得不分配另一个数组,复制原始数组的所有元素,并删除旧数组。在那之后, p 指向垃圾。这就是为什么许多操作 矢量 将使迭代器失效。

    似乎可以合理地假定,将使容器中的迭代器失效的操作也将使指向容器元素数据成员的指针失效,并且如果操作 使迭代器失效,这些指针仍然是安全的。然而,许多合理的假设都是错误的。这是他们中的一个吗?

    4 回复  |  直到 16 年前
        1
  •  11
  •   Potatoswatter    16 年前

    标准规定了这些指针何时失效。引用到 vector 当你增加它的尺寸时死亡 capacity 或添加/删除前面的元素。引用到 deque 如果从中间添加/删除,则无效。

    否则,在底层对象的生命周期内,引用和迭代器是安全的。

        2
  •  1
  •   anon    16 年前

    如果调整矢量的大小,则可以通过复制和/或赋值有效地重新创建内容。新包含的对象(可能)将位于不同的位置,因此指向或其成员的任何指针(可能)都将无效-您当然应该假定是这样。

        3
  •  1
  •   janks    16 年前

    是的,你的直觉是正确的。如果标准提到迭代器是无效的,那么它也倾向于声明引用也是无效的。

    例如,下面的部分文本描述了向量的“保留”成员函数的一些效果:

      Notes:
        Reallocation invalidates all the references, pointers, and iterators
        referring to the elements in the sequence. 
    

    我无法想象任何容器中的任何成员函数都会使特定元素的迭代器失效,但不会使指向这些相同元素的指针或引用失效,但我想我可能错了。

    最好检查标准对您的特定容器和成员函数所说的内容。

        4
  •  0
  •   Don Reba    16 年前

    您的假设对于向量是合理的,因为迭代器可以作为围绕指针的薄包装器实现。作为指针的替代,您可以存储到向量的偏移量。插入和删除会使它们失效,但不会通过内存重新分配而失效。