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

#include<cstdio>
#include<cstdlib>
#include<vector>

using namespace std;

class Node {
    int n;

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

vector<Node> v;

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

    return 0;
}

我在全局 vector 中插入了一个节点对象,并在局部 vector 中插入了该对象的指针。我上面的代码的输出是:
first node id : 1

但是,如果我将主要功能更改为此:
int main()
{
    vector<Node*> 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数据结构是否会更改每个对象的引用?
我怎样才能解决这个问题 ?

最佳答案

“vector 在插入后是否会更改引用?”

可能是的。当您添加/std::vector其他元素时, push_back() 可能会重新分配其(堆)存储,使所有指针无效:



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

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

上面的方法是,强烈建议不要使用。如果要使 vector 恒定(至少在要构造和使用第二个 vector 的函数范围内),则将有很强的保证不会重新分配。另外,如果您可以预先确定大小,则可以使用 std::array ,并且将指针用于该容器的存储更合适:



您可能还考虑将索引存储到 vector 中(尽管在那里, vector 可能会缩小,使索引无效,或者可能在中间插入元素等)。

无论如何,我怀疑您实际上可能不想做任何事情,即,对于一个可以用另一种方法完全解决的问题来说,这似乎不是一个很好的解决方案。

PS-如果 vector 具有custom allocator,则我编写的所有内容都可能无关紧要。

关于C++:指针 vector 在push_back()之后丢失引用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34708189/

10-12 00:10
查看更多