【问题标题】:Modifying a vector reference. What gets invalidated?修改矢量参考。什么会失效?
【发布时间】:2015-08-12 19:04:50
【问题描述】:

假设我有以下代码:

void appendRandomNumbers(vector<double> &result) {
    for (int i = 0; i < 10000; i++) {
        result.push_back(rand());
    }
}

vector<double> randomlist;
appendRandomNumbers(randomlist);
for (double i : randomlist) cout << i << endl;

重复的 push_back() 操作最终会导致重新分配,我怀疑内存损坏。 确实,vector.push_back() documentation

如果发生重新分配,所有与容器相关的迭代器、指针和引用都将失效。

重新分配发生后,哪些作用域将具有正确的向量? appendRandomNumbers 使用的引用是否无效,因此它将数字推送到不应该的位置,或者“正确”位置是否仅由 appendRandomNumbers 知道,并且一旦超出范围,向量就会被删除?

打印循环会遍历实际向量还是遍历该向量以前所在的陈旧内存区域?

编辑:现在大多数答案都说矢量引用本身应该没问题。我有一段类似于上面的代码,当我修改通过引用接收的向量时导致内存损坏,当我改变方法时停止内存损坏。不过,我不能排除我在更改期间偶然修复了真正的原因。将对此进行实验。

【问题讨论】:

  • 迭代器/指针和指向容器 in 数据的引用无效。容器本身并没有移动。如果对容器本身的引用无效,那将毫无价值。
  • 关于您的编辑:那段代码是错误的,或者您误解了结果。给出的答案是正确的。

标签: c++ memory vector memory-corruption


【解决方案1】:

我认为您对正在发生的事情感到困惑。 push_back() 可以使指向向量中对象的迭代器和引用无效,而不是向量本身。在您的情况下,不会有失效,并且您的代码是正确的。

【讨论】:

    【解决方案2】:

    引用vector&lt;double&gt; &amp;result 会很好,问题是如果你有一些引用底层内存的东西,例如

    double& some_value = result[74];
    result.push_back();   // assume this caused a reallocation
    

    现在some_value 引用了坏内存,使用data 访问底层数组也会发生同样的情况

    double* values = result.data();
    result.push_back();  // again assume caused reallocation
    

    现在values 指向垃圾。

    【讨论】:

      【解决方案3】:

      我认为您对无效的内容感到困惑。您示例中的所有内容都是完美的代码。问题是当您保留对向量本身拥有的数据的引用时。例如:

      vector<double> v;
      v.push_back(x);
      double& first = v[0];
      v.push_back(y);
      v.push_back(z);
      v.push_back(w);
      cout << first;
      

      这里,first 是对 v 内部数据的引用 - 可能push_back()s 之一无效,除非您特别考虑了额外的大小,否则您应该假设它无效,所以cout 是未定义的行为,因为first 是一个悬空引用。这就是您应该担心的事情 - 而不是您通过引用传递整个 vector 本身的情况。

      【讨论】:

        猜你喜欢
        • 2014-06-18
        • 1970-01-01
        • 1970-01-01
        • 2017-03-10
        • 2014-07-19
        • 1970-01-01
        • 1970-01-01
        • 2015-03-11
        • 2019-09-19
        相关资源
        最近更新 更多