【问题标题】:Do c++ references work like macro substitutions?c++ 引用是否像宏替换一样工作?
【发布时间】:2017-06-06 07:02:29
【问题描述】:
std::vector<int> v;
v.push_back(1);
int &r0=v[0],*p0=&v[0];
v.insert(v.begin(),0);
for (int i=2; i<1000000; i++) v.push_back(i);

在我插入和添加其他元素后,是否整个向量可能会转移到不同的内存位置?

那么 r0 和 p0 会返回什么?

如果向量发生了变化,我猜 p0 将指向垃圾,但引用仍然有效(即返回 0)?引用是否类似于宏替换?

【问题讨论】:

  • 宏替换与其他任何东西完全不同。您的代码将创建一个悬空引用
  • 矢量本身,v,永远不会移动。
  • 你确定 molbdnilo 吗? cplusplus.com/reference/vector/vector 声明“在内部,向量使用动态分配的数组来存储它们的元素。这个数组可能需要重新分配,以便在插入新元素时增大大小,这意味着分配一个新数组并将所有元素移动到它。就处理时间而言,这是一项相对昂贵的任务,因此,向量不会在每次将元素添加到容器时重新分配。”
  • std::vector::push_back: "如果新的 size() 大于 capacity() 则所有迭代器和引用(包括过去的迭代器)无效。否则只有过去的迭代器无效。" 来源:en.cppreference.com/w/cpp/container/vector/push_back
  • 谢谢理查德。这有帮助。

标签: c++ pointers vector reference


【解决方案1】:

引用与宏替换完全不同。

任何增加std::vector 大小的操作都会使其end() 迭代器无效。如果调整大小也增加了向量的容量(即重新分配底层内存),begin() 迭代器也会失效。

这意味着r0p0 都可能无效。如果不检查和比较调整大小前后v.capacity() 的结果(并确认容量没有变化),则不能保证r0p0 引用或指向向量v 的第一个元素.

用于更新向量大小和容量的策略是实现定义的。鉴于您的代码正在插入一百万零一个元素(1000001),容量很可能会在某个时候增加,并且r0p0 都已失效(即悬空) - 实际上, std::vector 的少数实现会使用在添加该数量元素时不需要调整大小的策略。因此,实际上,r0p0 都无效。

向量的地址(即&amp;v)不会改变。由vv.capacity()v.size()v.data()v.begin()v.end() 等)管理的数据的特征将(可能)发生变化。

【讨论】:

  • 谢谢彼得。我认为是在参考描述中使用“别名”这个词让我大吃一惊。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 2018-11-10
  • 1970-01-01
  • 2015-01-03
相关资源
最近更新 更多