2

假设我有以下内容:

struct Foo {
Foo () : bar(NULL), box(true) {}
Bar* bar;
bool box;
};

我声明如下:

std::vector<Foo> vec(3);

我现在有一个函数可以执行以下操作:

Foo& giveFoo() { //finds a certain foo and does return vec[i]; }

Foo然后调用者将它通过引用获得的地址传递Foo*给其他人。但是,我想知道的是,Foo在触发向量增长后,这个指向的指针是否仍然有效vec?如果复制其中的现有Foo元素,vec那么大概Foo*漂浮的元素现在将悬空?是不是这样?我正在调试应用程序,但无法重现。

4

4 回答 4

5

重新分配向量时,任何指向元素的指针或引用都将失效,就像任何迭代器一样。

于 2014-02-12T15:31:40.207 回答
3

指针将保持有效,直到您在向量上调用非常量成员函数:

  • 导致其大小超出其容量(发生这种情况时,内部存储将被重新分配,并且对元素的所有指针和引用都将失效)或

  • 在指针指向的元素之前插入一个元素,或

  • 从向量中删除元素,或

  • 从位于指针指向的元素之前的向量中删除一个元素。

前两个子弹可以同时发生。不同之处在于,只要大小不超过容量,指向位于插入点之前的元素的引用/指针仍然有效。

于 2014-02-12T15:37:41.723 回答
1

是的,它可能会变得无效,因为基本上当vector需要增加它的保留大小时,它只是删除它的内部存储(基本上是一个数组),分配扩大的一个并在那里复制它以前的内容。

如果您确定该索引保持不变,尽管您可以在每次需要时使用该索引来访问所需的数据。

于 2014-02-12T15:34:00.353 回答
1

以下是标准对向量修饰符的向量迭代器有效性的说明:

vector::push_back(), vector::insert(), vector::emplace_back(), vector::emplace():

如果新大小大于旧容量,则导致重新分配。如果没有发生重新分配,则插入点之前的所有迭代器和引用仍然有效。

vector::erase()

在擦除点或之后使迭代器和引用无效。

除此之外的任何假设都是不安全的。

于 2014-02-12T15:35:34.943 回答