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

C++迭代器调用类中链表getter时触发段错误的原因

问题分析:为什么第一次迭代触发段错误?
#include <iostream>
#include <list>

using namespace std;
class A{
  private:
      list<int*> data;

  public:
      A(list<int*> data_){data=data_;}
      list<int*> getData(){return data;}
};

int main(){
  list<int*> temp;
  temp.push_back(new int(1));
  temp.push_back(new int(2));
  temp.push_back(new int(3));
  temp.push_back(new int(4));

  A a(temp);

  // First Iteration
  list<int*>::iterator it;
  cout<<(a.getData()).size()<<endl;
  for (it = (a.getData()).begin(); it != (a.getData()).end(); it++)
      cout << *(*it) << endl;
  
  // Second Iteration
  list<int*> mylist = a.getData();
  for (it = mylist.begin(); it != mylist.end(); it++)
      cout << *(*it) << endl;
}

上述代码中,第一次迭代会触发segmentation fault(段错误),但第二次迭代不会,请问第一次迭代出现段错误的原因是什么?


原因解析

核心问题出在getData()的返回值性质上:

  • list<int*> getData()的返回类型是list的副本,而非原对象的引用。
  • 第一次迭代时,(a.getData())每次调用都会生成一个临时的list对象。当执行it = (a.getData()).begin()这条语句后,这个临时对象会立即被销毁,此时it就变成了悬空迭代器——指向一块已经被释放的内存空间。后续循环中通过这个迭代器访问元素,直接触发了内存访问错误,也就是段错误。
  • 第二次迭代时,我们把getData()返回的副本赋值给了局部变量mylist,mylist的生命周期覆盖了整个循环过程。迭代器指向的是mylist这个有效存在的list,因此访问元素不会出现问题。

如果要避免这类问题,可以把getData()的返回类型修改为const list<int*>&(返回原对象的常量引用),这样就不会生成副本,迭代器也能指向有效内存。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:55:01