为什么vector :: erase()不会使对擦除元素的引用无效?

时间:2014-04-02 16:25:20

标签: c++ vector stl reference

请考虑以下代码:

vector<int> test = { 0, 1, 2 };
test.push_back(3);   
int& last = test.back();
test.pop_back();    //now last_elem_ref should be invalid, right?
3 == last; //evaluates to true o.O
last = 5;  // this works just as fine 

我知道没有任何引用不存在,但我不知道它是如何工作的。 C ++没有垃圾收集器或引用计数(当然除了智能指针),所以为什么在它的所有者转储它时对象不会被销毁?

或者它被破坏了,引用甚至不再引用该值了?

什么时候会被销毁,例如什么时候它占用的内存会被释放?(我的个人猜测是,一旦对象的最后一次引用超出范围。)

3 个答案:

答案 0 :(得分:4)

  

我知道没有任何内容的引用不存在

是的,他们这样做:就像指针一样,如果引用的对象被破坏,引用可以无效并悬空。使用无效引用会给出未定义的行为。

  

当它的拥有者抛弃它时,为什么不破坏该对象?

是的。但是破坏一个对象并不一定会使它占用的内存不可访问。在这种情况下,内存仍由vector管理,并且访问它可能会为您提供旧值,因为没有任何内容覆盖它。或者它可能会导致其他形式的未定义行为。

  

什么时候会被销毁,例如它占用的内存何时会被释放?

当向量被销毁时,或者当它重新分配其数组时,内存将被释放。它可能仍然可以访问;小块通常返回到堆中以供重用,而不是从进程的内存空间中取消映射。

  

我的个人猜测是,一旦对象的最后一次引用超出范围。

没有。如你所说,C ++中没有引用计数。自动对象在超出范围时会被销毁,而动态对象在被明确销毁时会被销毁,无论它们是否引用它们。

答案 1 :(得分:1)

引用仍然指的是值所在的内存位置,并且还没有更改内存位置的内容。

未定义的行为 - 无法保证该内存的内容,甚至是不会崩溃的内容。

答案 2 :(得分:1)

实际上,内存仍然已分配,但这并不意味着您可以使用它:-)这是std::vector内部管理内存的直接结果。永远不会释放记忆,除非你clear()

如果您尝试其他push_back,则应该影响last引用的值。

同样,要明确,不要依赖于此,这是一种不好的做法,可能是未定义的行为。