循环迭代后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
相关产品推荐
相关产品推荐

