当前位置:  开发笔记 > 编程语言 > 正文

C++:指针向量在push_back()之后失去引用

如何解决《C++:指针向量在push_back()之后失去引用》经验,为你挑选了1个好方法。

在我的代码中,a有一个Node对象的全局向量和一个Node指针的局部向量:

#include
#include
#include

using namespace std;

class Node {
    int n;

public:
    Node(int i) : n(i);
    int getN() { return n; }
};

vector v;

int main() {
    vector p;
    v.push_back(Node(1));
    p.push_back(&v[0]);
    printf("first node id : %d\n", (*p[0]).getN());

    return 0;
}

我将一个节点对象插入到全局向量中,并将该对象的指针插入到本地向量中.我上面代码的输出是:

first node id : 1

但是,如果我将主要功能更改为:

int main()
{
    vector p;
    v.push_back(Node(1));
    p.push_back(&v[0]);
    v.push_back(Node(2));
    p.push_back(&v[1]);
    printf("first node id : %d\n", (*p[0]).getN());

    return 0;
}

代码打印垃圾值:

first node id : 32390176

我无法弄清楚这个问题.vector插入后数据结构是否会更改每个对象的引用?我怎样才能解决这个问题 ?



1> einpoklum - ..:

"插入后向量是否会更改引用?"

可能,是的.一个std::vector 时添加/可重新分配其(堆)存储push_back()的附加元件,无效所有的指针:

迭代器[读取:指针]失效

(用于操作)push_back,emplace_back...如果向量改变了容量,则所有这些[即所有迭代器都无效].如果没有,只有end().

"我怎样才能解决这个问题?"

如果向量的容量由于插入而没有改变,则上述失效规则不适用 - 因为向量不会不必要地重新分配存储.因此,如果您在示例中预先将矢量的容量设置为2(例如,with v.reserve(2)),则指针将保持有效.如果你事先不知道大小,但你可以延迟第二个向量的构造(使用指针),你不必保留,你只需要插入最后一个元素后的大小.

然而,上述方法是非常不受推荐的.如果你要使向量保持不变 - 至少在你将构造和使用第二个向量的函数范围内 - 你将有一个强大的非重新分配保证.或者,如果您可以提前确定大小,则可以使用a std::array,并且将指针用于该容器的存储更为合适:

迭代器失效

通常,数组的迭代器在数组的整个生命周期中永远不会失效.

您也可以考虑将索引存储到向量中(尽管也存在向量可能缩小,索引无效,或者您可能在中间插入元素等).

无论如何,我怀疑你可能实际上并不想做任何这样的事情,即它似乎是一个不太好的解决方案,可以用一个完全不同的方法处理问题.

PS - 如果向量具有自定义分配器,那么我写的所有内容都可能无关紧要.

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有