C++类内外访问map中同一数据取值不一致问题排查
问题根因
这是典型的*悬空指针(野指针)*错误,和map_Data结构体使用bool还是int类型没有关系,错误来自对局部变量生命周期的错误使用:
- 你在
build_BDDs函数中定义的map_Data txt是分配在栈上的局部变量,它的生命周期仅存在于build_BDDs函数执行期间。函数执行完成返回后,该变量占用的栈内存会被系统自动回收复用。 - 你将局部变量
txt的地址&txt存入了map中,函数退出后这个地址指向的内存已经失效,后续再通过这个地址访问数据,读到的是被其他操作覆写的脏数据,结果自然不符合预期。 - 额外注意:你在
main函数中定义的map_Data a也是栈上局部变量,把它的地址存入全局outs的写法同样存在悬空指针风险,只是因为main函数在程序运行全程不会退出,暂时没有触发异常。
输出结果解释
你得到的运行输出完全符合悬空指针的表现:
- 函数内部执行打印时,
txt还在生命周期内,对应内存没有被回收覆写,所以能正确读到hi=1、lo=0,输出1;0 - 函数返回后,
txt对应的栈空间被释放,后续执行cout打印逻辑时,这块内存被临时运算数据覆写,因此通过outs中存储的失效指针访问,读到的是无意义的脏数据,此处表现为0;0 - 返回值
b是函数返回时做的值拷贝,会把return执行时刻txt里的数值完整复制到b的独立内存空间中,因此b的取值始终是正常的1;0
修复方案
你可以根据业务需求二选一:
- 方案1(推荐,无内存管理成本):map中不存储指针,直接存储结构体值,由map容器自动管理内存,从根源避免悬空指针问题。
修正后的核心代码如下:#include <bits/stdc++.h> using namespace std; struct map_Data{ bool hi; bool lo; }; // 直接存结构体值,不存指针 map<pair<int, int>, map_Data> outs; class MWVC{ public: map_Data build_BDDs(map<pair<int, int>, map_Data> & ins){ map_Data txt; txt.hi = 1; txt.lo = 0; ins[make_pair(2,4)] = txt; cout << ins[make_pair(2,4)].hi << ";" << ins[make_pair(2,4)].lo << endl; return ins[make_pair(2,4)]; } }; int main(){ MWVC ojb; map_Data a; a.hi = 1; a.lo = 0; outs[make_pair(1,2)] = a; // 直接判断键是否存在,不要判断指针是否非空 if(outs.count(make_pair(1,4))){ cout << outs[make_pair(1,4)].hi << endl; } map_Data b = ojb.build_BDDs(outs); cout << outs[make_pair(2,4)].hi << ";" << outs[make_pair(2,4)].lo << ";" << b.hi << ";" << b.lo << endl; return 0; } - 方案2:如果业务逻辑必须存储指针,就不要使用栈上局部变量的地址,改用
new在堆上分配内存,手动控制对象生命周期,注意对象使用完成后要主动delete释放内存,避免内存泄漏。
核心修改点:map_Data build_BDDs(map<pair<int, int>, map_Data*> & ins){ // 堆上分配内存,不会随函数退出自动回收 map_Data* txt = new map_Data(); txt->hi = 1; txt->lo = 0; ins[make_pair(2,4)] = txt; cout << ins[make_pair(2,4)]->hi << ";" << ins[make_pair(2,4)]->lo << endl; return *ins[make_pair(2,4)]; }
内容的提问来源于stack exchange,提问作者JI HAO
相关产品推荐
相关产品推荐

