vector.back()的意外值

时间:2013-05-23 10:57:05

标签: c++ pointers vector

我一直在想着这个。

#include <iostream>
#include <vector>

int main() {

    std::vector<int> a;
    std::vector<int *> b;

    a.push_back(13);
    b.push_back(&a.back());

    a.push_back(24);
    b.push_back(&a.back());

    for (std::vector<int>::iterator it = a.begin(); it != a.end(); ++it)
        std::cout << *it << " ";
    std::cout << "\n";

    for (std::vector<int *>::iterator it = b.begin(); it != b.end(); ++it)
        std::cout << *(*it) << " ";
    std::cout << "\n";

    return 0;
}

输出:

13 24
16712910 24

我真的很想知道为什么两条输出线都不匹配。我在这里错过了什么?我用gcc 4.6.3

编译了这个

5 个答案:

答案 0 :(得分:2)

由于vector在第二个push_back期间增长并重新分配元素,因此发生了这种情况。当您执行第二个push_back时,向量可能会发现其容量已满并分配新空间并将元素移动到新内存。它还释放了先前分配的内存。由于您正在存储此已释放内存位置的地址,因此您会看到垃圾值。要解决此问题,您需要执行a.reserve(2),以便在push_back为2 ints期间向量不会重新分配。

答案 1 :(得分:1)

a.push_back()的第二次调用可能(在这种情况下显然会)通过重新分配整个内存量来更改a中第一个元素的地址。因此,&a[0]b[0]中存储的地址不再匹配。

尝试:

int main() {
  std::vector<int> a;
  a.push_back(13);
  std::cout << &a[0] << endl;
  a.push_back(24);
  std::cout << &a[0] << endl;
  return 0;
}

您很可能会看到不同的值:)

答案 2 :(得分:0)

vector实现动态数组:当你push_back时,可以重新分配数组 - 移动到内存中的另一个位置。但是,当移动b所拥有的数组时,您将推送到a的值不会更新。他们指向无人的土地,访问b[0]导致未定义的行为。在这种情况下,读取随机值。

答案 3 :(得分:0)

如果重新调整初始(a)向量,则b中的元素将指向无效值。 为了确保它的工作原理,我们必须事先知道我们要插入的最大元素,并在插入元素之前设置容量。

答案 4 :(得分:0)

当将新元素插入Vector并超出其容量时 - 它重新分配内存,所有先前获得的直接引用都会被破坏,因为所需的信息不再存在。