【问题标题】:std::transform producing strange outputstd::transform 产生奇怪的输出
【发布时间】:2014-08-01 00:34:59
【问题描述】:

今天我在玩一些标准库函数.. 并且发现每当容器正在使用(在本例中为向量)中包含超过 2 个元素时 std::transform() 和 std::back_inserter 的这个奇怪输出.我不明白这种行为那里​​的任何人都可以帮助我......

#include<iostream>  
#include<algorithm>  
#include<vector>  
using namespace std;  

/* this version of change works fine for me when i store the incoming value into a   
   static variable  
int change(int n){  
 static int m=n;
 return m * m;  
}*/  

int change(int n){  
return n*n;  
}  

int main(){  
 vector<int> v2(3,3),  
            v1;  

 transform(v2.begin(),v2.end(),back_inserter(v2),change);  

 for(auto v: v2)  
  {   
    cout << v <<"  ";  // prints out a strange random 5th value in v2.  

  }  
 return 0;  
}  

【问题讨论】:

  • 当容器用作算法的输入时,通常不允许在算法执行期间修改容器或使迭代器无效。
  • 请避免在代码块中出现长行。不是每个人都在配备超宽显示器的台式机上使用最大化的浏览器查看这些页面。
  • 顺便说一句:UB has a time-machine,因此由于程序在任何可能的执行过程中都会遇到它,因此程序从一开始就具有未定义的行为。

标签: c++ c++11 stl


【解决方案1】:

最可能的原因是当您将push_back 元素放入其中时,正在重新分配vector 的存储空间(这就是分配给back_insert_iterator 的结果)。这会使传递给transformbeginend 迭代器无效,并且后续的赋值会导致未定义的行为。

如果您在拨打transform之前reserve()vector有足够的空间,您的问题就可以解决

vector<int> v2(3,3);

v2.reserve(v2.size() * 2);
transform(v2.begin(),v2.end(),back_inserter(v2),change);

这会产生所需的输出。

3 3 3 9 9 9

Live demo

【讨论】:

  • 感谢工作......但是当我将传入迭代器的值存储到静态变量中并返回它时,该函数工作......
  • @user3104126 这仍然是未定义的行为,因为一旦vector 第一次调整大小,transform 就会取消引用无效的迭代器。它似乎可以工作,因为通过在change 中创建m static,您一次 使用传递给change 的参数初始化它,然后继续返回它的平方价值。因此,您永远不会在第一次调用后使用传递给change 的无效值。尝试将v2[0] = 1; 添加到static 版本中,您会看到添加的所有新元素都是1,并且不依赖于剩余的vector 元素。
  • 非常感谢...好吧,我没有使用传递给函数的无效值...再次感谢。
猜你喜欢
  • 2021-07-26
  • 2020-05-14
  • 2020-11-18
  • 2015-08-18
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
  • 2012-07-19
  • 2023-01-10
相关资源
最近更新 更多