C++中指针类型map的正确插入方式探讨
两种map插入元素方式的正确性与优劣分析
定义的结构体与类
struct myStruct { int a; int b; int c; }; class myClass { map<int, myStruct*> myMap; int i; //还有其他成员变量与函数 public: void doFunc(); };
针对同一个myClass对象,doFunc()会被多次调用,i的取值范围为0-100。以下两种向map中插入元素的方式哪种更正确/更优?
方式一
void myClass::doFunc() { myStruct obj; obj.a = 1; obj.b = 2; obj.c = 3; myMap[i] = &obj; i++; }
方式二
void myClass::doFunc() { myStruct* obj = new myStruct(); obj->a = 1; obj->b = 2; obj->c = 3; myMap[i] = obj; i++; }
注:动态分配的内存会在myClass的析构函数中释放;实际代码中myStruct还有大量其他成员变量,目前暂不使用构造函数,后续会重构代码。
分析结论
方式一完全错误,绝对不能使用
myStruct obj是栈上的局部变量,当doFunc()执行结束时,这个局部变量会被立即销毁,对应的内存空间会被系统回收。此时myMap中存储的指针就变成了野指针,后续任何访问该指针的操作都会触发未定义行为——可能导致程序崩溃、读取到乱码数据,甚至引发更隐蔽的逻辑错误。方式二是正确可行的
用new动态分配的内存位于堆区,不会随着doFunc()的结束而销毁,只要在myClass的析构函数中遍历myMap,对每个指针调用delete释放内存,就不会出现内存泄漏问题。在i仅0-100的调用次数下,动态分配的性能开销可以完全忽略,完全适配当前场景。
另外补充两个优化建议:
- 后续重构时,建议给
myStruct添加构造函数,简化成员变量的初始化代码; - 可以考虑用
std::unique_ptr<myStruct>替代裸指针存入map,这样无需手动在析构函数中释放内存,能大幅降低内存泄漏的风险,代码也更安全简洁。
内容的提问来源于stack exchange,提问作者arjun gulyani
相关产品推荐
相关产品推荐

