You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

直接传递容器与传递容器引用的差异及set迭代器异常问题

C++容器传值与传引用的区别及std::set迭代器问题解析

1. 直接传递容器与引用传递容器的区别

  • 内存开销与性能:直接传值会创建容器的完整副本,所有元素都会被复制,容器越大、元素越复杂,开销越高;引用传递只是传递容器的内存地址,没有复制操作,性能更优。
  • 修改影响范围:传值时函数内修改的是副本,原容器不会有任何变化;非const引用传递时,函数内对容器的修改会直接作用于原容器。
  • 迭代器有效性:传值得到的副本是独立容器,原容器的迭代器无法和副本的迭代器(包括end())做有效比较;引用传递则始终指向原容器,迭代器的比较逻辑完全有效。

2. std::set传值导致无限输出的原因

两段代码的核心差异就是第二个参数的传递方式:一个是传值std::set<int> s,一个是传引用std::set<int>& s,问题出在迭代器和容器的绑定关系上。

传值版本的问题分析

  1. 调用f(s.begin(), s)时,itr是原set的起始迭代器,而函数参数s是原set的全新副本,和原容器完全独立。
  2. 函数内判断itr != s.end()时,s.end()是副本set的尾迭代器,但itr属于原容器,两者分属不同实例,这个比较的结果是未定义行为——实际运行中会一直返回true,永远不会触发退出条件。
  3. 随着递归调用,itr不断自增,当走到原set的尾迭代器之后,继续自增会进入内存的未定义区域,输出垃圾数值,形成无限序列。

传引用版本的正常逻辑

  1. 调用f(s.begin(), s)时,s是原set的引用,和itr属于同一个容器实例。
  2. itr != s.end()的比较是同一容器内迭代器的有效比较,当itr走到原set的尾迭代器时,条件不成立,递归终止。
  3. 因为std::set是有序容器,元素会自动排序为-8,1,2,3,7,所以输出序列是-81237。

内容的提问来源于stack exchange,提问作者ilsec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:30:58