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

循环迭代后vector内容丢失问题及解决方案咨询

问题分析与修复方案

问题核心

你遇到的乱码和vector清空问题,根本原因不是vector被编译器主动删除,而是你在循环里创建了原对象的局部拷贝,修改完拷贝后又把局部对象的地址存回map,迭代结束后局部对象销毁,map里的指针变成野指针,后续访问这些指针指向的内存就会出现乱码甚至崩溃。

你的核心错误代码片段:

// 把map里的指针解引用,拷贝出局部对象
row rowobj = *rowdict.at(i);
col colobj = *coldict.at(i);
sqdiv sq = *sqdict.at(sq_decider_ret);

// 修改的都是局部拷贝的成员
// ...

// 把局部对象的地址存回map,迭代结束后这些对象就销毁了
coldict[i] = &colobj;
rowdict[i] = &rowobj;
sqdict[sq_decider_ret] = &sq;

修复步骤

1. 直接操作原对象,避免局部拷贝

不要创建局部拷贝,直接用指针访问map里的原对象,修改的就是真实对象的属性,不需要再把指针存回map(因为指针本身没变,修改的是指针指向的内容):

修正后的核心代码:

map<int, row*> solver(  map<int, row*> rowdict,
                        map<int, col*> coldict,
                        map<vector<int>, sqdiv*> sqdict  )
{
      for (int i_j_sum = 2;  i_j_sum <= 18; i_j_sum++)
      {
            for (int i=1; i <= i_j_sum-1; i++)
            {
                  vector<int> slot = {i, i_j_sum - i};
                  // 直接获取原对象的指针,不做拷贝
                  row* rowptr = rowdict.at(i);
                  col* colptr = coldict.at(i);
                  vector<int> sq_decider_ret = sq_decider(slot);
                  sqdiv* sqptr = sqdict.at(sq_decider_ret);

                  vector<int> tot_available = intersector(colptr->available, rowptr->available, sqptr->available);
                  int val = rand_from_vect(tot_available);

                  // 直接修改原对象的vector成员
                  for (vector<int>::iterator it = colptr->available.begin(); it != colptr->available.end(); )
                  {
                        if (*it == val)
                              it = colptr->available.erase(it);
                        else
                              ++it;
                  }
                  for (vector<int>::iterator it = rowptr->available.begin(); it != rowptr->available.end(); )
                  {
                        if (*it == val)
                              it = rowptr->available.erase(it);
                        else
                              ++it;
                  }
                  for (vector<int>::iterator it = sqptr->available.begin(); it != sqptr->available.end(); )
                  {
                        if (*it == val)
                              it = sqptr->available.erase(it);
                        else
                              ++it;
                  }

                  rowptr->slots.push_back(val);

                  // 无需再存指针回map,原对象已被直接修改
            }
      }
      return rowdict;
}

2. 关于vector生命周期的问题

你问能不能让循环内定义的vector处于全局作用域或者不被删除——完全没必要。只要vector是存活对象的成员(比如map里row、col、sq对象的available成员),只要这些对象本身没被销毁,vector就会一直存在。你之前的问题是修改的是局部拷贝的vector,拷贝对象销毁后,对应的vector自然也被销毁了,和全局作用域无关。

如果确实需要在循环内创建新vector并赋值给对象属性,直接创建后赋值即可(比如rowptr->available = new_vector;),只要对象本身存活,这个新vector就会被对象持有,不会被销毁。

额外注意点

  • 函数参数里的rowdict、coldict、sqdict是按值传递的,会被拷贝一份,你在函数里修改的是拷贝后的map,原map不会受到影响。如果需要修改原map,应该把参数改成引用:map<int, row*>& rowdict。
  • 确保map里的指针指向的对象在整个函数执行期间都是存活的,不会被提前销毁,否则还是会出现野指针问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 05:24:07