如何用new初始化含2个对象的数组并将首元素指针存入std::map?
正确实现方式及错误分析
先理清你之前写法的问题
- 错误写法1:
MyClass myobj[2];是在栈上创建了2个MyClass对象,但后面myobj[0] = new MyClass(...)是把指针赋值给对象实例,类型完全不匹配。而且栈上的数组在StartupRoutine函数执行完后会被销毁,你把栈地址存到map里,后续访问会触发野指针错误。 - 错误写法2:
myobj+1是指针算术运算后的右值,你不能给右值赋值,这种写法本身就是语法错误,编译器直接会报错。 - malloc写法崩溃原因:
malloc只分配了内存空间,没有调用MyClass的构造函数。直接用*MyObj = MyClass(...)是用临时对象拷贝赋值,但如果MyClass包含SDL纹理句柄、动态分配的内存这类资源,拷贝赋值不会正确初始化对象的内部状态,调用方法时自然会崩溃。
正确实现代码
要满足「兼容单个/2个/4个对象数组、能通过指针偏移访问」的需求,直接用new[]创建堆上的对象数组即可——new[]会自动调用每个元素的构造函数,且堆内存不会随函数结束销毁,适合存入map。
1. 创建2个对象的数组并存入map
// 创建包含2个MyClass对象的堆数组,自动调用每个元素的构造函数 MyClass* objArray = new MyClass[2]{ MyClass(/* 第一个对象的构造参数 */), MyClass(/* 第二个对象的构造参数 */) }; // 调用setters初始化 objArray[0].SetSomeValue(xxx); objArray[1].SetAnotherValue(yyy); // 存入map,数组首地址就是objArray,等价于&objArray[0] mymap["something"] = objArray;
2. 访问对象方法(兼容偏移写法)
// 访问第一个对象 mymap["something"]->MyMethod(); // 或者用数组下标 (*mymap["something"])[0].MyMethod(); // 访问第二个对象,用指针偏移 (mymap["something"] + 1)->MyMethod(); // 或者数组下标 (*mymap["something"])[1].MyMethod();
3. 兼容单个对象的情况
单个对象可以看成长度为1的数组,写法一致:
MyClass* singleObj = new MyClass[1]{ MyClass(/* 构造参数 */) }; mymap["single"] = singleObj; // 访问方法 mymap["single"]->MyMethod(); // 或者偏移0(等价) (mymap["single"] + 0)->MyMethod();
4. 创建4个对象的数组
MyClass* fourObjArray = new MyClass[4]{ MyClass(/* 参数1 */), MyClass(/* 参数2 */), MyClass(/* 参数3 */), MyClass(/* 参数4 */) }; mymap["four"] = fourObjArray; // 访问第三个对象 (mymap["four"] + 2)->MyMethod();
注意事项
- 一定要记得在程序退出或者不需要这些对象时,用
delete[]释放内存,避免内存泄漏:for (auto& pair : mymap) { delete[] pair.second; } mymap.clear(); - 如果
MyClass的构造函数不需要参数,new MyClass[2]会默认初始化每个元素,不用写大括号里的内容。
内容的提问来源于stack exchange,提问作者Borbi
相关产品推荐
相关产品推荐

