使用C++ std::copy反转vector元素出错,请求排查问题原因
为什么用std::copy反转vector会得到错误结果?
我想要反转vector中的元素,因此尝试用reverse函数和copy函数。reverse函数运行正常,但用copy函数结合反向迭代器时得到了错误结果。
代码如下:
#include <iostream> #include <vector> #include <list> #include <algorithm> #include "show.h" int main() { std::vector<int> v = { 1,2,3,4,5,6,7,8,9,10 }; std::list<int> s = { 1,2,3,4,5,6,7,8,9,10 }; std::copy(v.rbegin(), v.rend(), v.begin()); show(v); // 预期结果: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 // 实际结果: 10, 9, 8, 7, 6, 6, 7, 8, 9, 10 return 0; }请问我的代码存在什么问题?
问题根源
你的代码出错是因为输入迭代器范围和输出迭代器范围重叠,而std::copy不支持处理这种重叠场景。
当执行std::copy(v.rbegin(), v.rend(), v.begin())时:
- 前5次复制会把反向序列的前5个元素(10、9、8、7、6)写入vector的前5个位置,此时vector后5个元素(原本是5、4、3、2、1)还未被修改;
- 后续复制需要读取反向序列的后半段,对应原vector的后5个位置,但此时这些位置已经被前面的操作覆盖(比如原索引5的位置被改成了6),导致后续读取的是被修改后的元素,最终得到错误的后半段序列。
std::copy的设计逻辑是假设输入和输出范围无重叠,一旦重叠就会出现数据覆盖的问题。
解决方案
优先使用
std::reverse(最推荐)
这是C++标准库专门用于反转容器的函数,内部已经处理了重叠范围的问题,用法简单高效:std::reverse(v.begin(), v.end());执行后vector会直接被正确反转成
10,9,8,7,6,5,4,3,2,1。若必须使用copy类函数
可以先把反向序列复制到临时容器,再拷贝回原vector,避免重叠覆盖:std::vector<int> temp(v.rbegin(), v.rend()); std::copy(temp.begin(), temp.end(), v.begin());
内容的提问来源于stack exchange,提问作者jslee
相关产品推荐
相关产品推荐

