【问题标题】:What does taking address of return from std::vector::operator[] do?从 std::vector::operator[] 获取返回地址有什么作用?
【发布时间】:2012-01-25 21:48:29
【问题描述】:

我正在做类似的事情:

struct ABC{
int p,q,r;
};

struct X{
ABC *abc;
X(ABC &abc) : abc(&abc) {}
};

std::vector<ABC> vec;
... //populate vec

X x(vec[2]);

当我调试时,x.abc 在赋值后直接看起来是正确的,但不久之后 x.abc 中的数据就是垃圾。这让我觉得指针指向一个局部变量......但是vector::operator[] 返回一个引用,所以这可能吗?

【问题讨论】:

  • 更新了一点,希望更清楚。

标签: c++ pointers stl vector


【解决方案1】:

在内部,std::vector 通常维护其包含的元素的动态数组。如果向量的大小变得太大并超过其旧容量,它会分配一个新数组,复制旧元素,然后释放旧数组。因此,任何指向该旧数组的引用或指针都会变得无效,并且如果使用将导致未定义的行为。

如果要将指针存储到向量中,则应确保向量最终不会重新分配其内部缓冲区。为此,您可以等到所有要添加到向量中的元素都添加完毕后再进行引用,或者调用vector::reserve 以确保容量足够大。

不过,更好的是,将vector 对象本身的引用与索引一起存储,然后每次都在该索引处查找元素。这样,如果向量调整其内部缓冲区的大小,您的指针就不会变成垃圾,因为您每次都在重新索引向量。

希望这会有所帮助!

【讨论】:

  • 这可能是std::deque&lt;&gt; 而不是std::vector&lt;&gt; 的一个很好的用例。
  • @ildjarn:指向deque 的指针可能会失效我相信,您是否可能在考虑list
  • @Jesse :虽然迭代器将失效,但 pointers/referencesstd::deque&lt;&gt; 不会在前插入或后插入 deque 时失效,因为它不需要像 std::vector&lt;&gt; 那样潜在地重新分配现有元素(参见 C++11 §23.3.3.4/1)。
  • @ildjar:我明白了,只要他们不要t do an insert`。
  • @Jesse : 即使insert 也可以,只要它在前面或后面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
  • 1970-01-01
相关资源
最近更新 更多