当std :: vector增长时,其中的元素的地址不再有效吗?

时间:2014-02-12 15:27:55

标签: c++ vector dangling-pointer

假设我有以下内容:

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*元素被复制,那么大概是浮动的{{1}}现在会悬空?是这种情况吗?我正在调试一个应用程序,但无法重现它。

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

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

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

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

  • 从矢量中删除元素,或

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

以下是关于矢量修改器矢量迭代器有效性的标准说明:

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

  

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

vector::erase()

  

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

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