交换向量和指针无效

c++: swapping vectors and pointer invalidation?

本文关键字:无效 指针 向量 交换      更新时间:2023-10-16

我似乎有一个问题,交换两个向量的元素。我有两个向量,xy,它们包含类型为myclass的对象。myclass只有一个公共成员w。我创建了一个指向x的成员w的指针向量,然后交换向量xy。我希望指针向量仍然指向xw成员,但情况似乎并非如此。

这里有一个简单的例子来重现我的问题。

#include <iostream>
#include <vector>
using namespace std;
struct myclass
{
    double w;
};

int main()
{
    vector<myclass> x(10);
    for(int i=0; i!=10; i++) x[i].w = i;
    for(auto el : x) std::cout << el.w << std::endl; /* prints i */
    std::cout << std::endl;
    vector<double *> px(10);
    for(int i=0; i!=10; i++) px[i] = &x[i].w;
    for(auto el : px) std::cout << *el << std::endl; /* prints i */
    std::cout << std::endl;
    vector<myclass> y(10);
    for(int i=0; i!=10; i++) y[i].w = 2*i;
    for(auto el : y) std::cout << el.w << std::endl; /* prints 2*i */
    std::cout << std::endl;
    y.swap(x);
    for(auto &el : x) std::cout << &el.w << " " << el.w << std::endl; /* prints 2*i as it should */
    std::cout << std::endl;
    for(auto &el : px) std::cout << el << " " << *el << std::endl; /* should print 2*i, but prints i */
    std::cout << std::endl;
}

注意xy交换了元素,但px仍然指向旧的元素。我读到使用swap不应该使指针/迭代器无效。这是对的吗,还是我遗漏了什么?提前感谢!

指针和迭代器不会失效,但它们遵循容器的内容。

x的内容被交换到y,但是迭代器和指向这些值的指针仍然指向它们(即使它们现在在y中)。

想想看,它怎么可能以其他方式工作呢?如果交换两个长度不等的容器,则指向较长容器末尾附近元素的指针在较短容器中指向什么?如果每个容器的元素都必须在内存中移动以确保指针保持有效,那么如何在O(1)中实现swap()呢?