C++中map迭代器转对象指针并设置类成员指针问题
解决map存储对象指针后数据错乱的问题
核心问题定位
你遇到的数据错乱(frame显示超大整数)是悬空指针导致的:在Player::initAnimations()中创建的是局部Animation对象,函数执行完成后,局部对象会被自动销毁,此时Animations类的map<string, Animation*>里存储的指针就指向了已经被释放的内存空间,后续访问这个指针时,读取的是内存里的垃圾数据,自然出现异常值。
解决方案
1. 改用动态分配对象(手动管理内存)
把局部对象改成用new创建的动态对象,确保对象生命周期不受函数栈影响:
// Player::initAnimations() 中的代码修改 Animation* idleAnim = new Animation(); idleAnim->frame = 0; animations.add("idle", idleAnim);
注意:需要在Animations类的析构函数中遍历map,手动释放每个Animation对象的内存,避免内存泄漏:
Animations::~Animations() { for (auto& pair : animMap) { delete pair.second; } }
2. 用智能指针自动管理内存(推荐)
将map的存储类型改为智能指针(比如std::unique_ptr或std::shared_ptr),无需手动释放内存,从根源避免悬空指针和内存泄漏:
// Animations类中的容器定义修改 #include <memory> std::map<std::string, std::unique_ptr<Animation>> animMap; // 对应的add方法修改 void add(const std::string& name, std::unique_ptr<Animation> anim) { animMap[name] = std::move(anim); } // Player::initAnimations() 中的创建逻辑 auto idleAnim = std::make_unique<Animation>(); idleAnim->frame = 0; animations.add("idle", std::move(idleAnim));
3. 存储对象副本(避免指针)
如果不想使用指针,需要确保Animation类有可用的拷贝/移动构造函数,解决“无匹配构造函数初始化Animation”的错误:
// Animation类中添加拷贝构造函数 class Animation { public: int frame = 0; // 手动定义拷贝构造,或用default让编译器生成默认版本 Animation(const Animation& other) : frame(other.frame) {} // 或者 Animation(const Animation&) = default; }; // Animations类中的容器改为存储对象 std::map<std::string, Animation> animMap; // add方法修改为接收对象或常量引用 void add(const std::string& name, const Animation& anim) { animMap[name] = anim; } // Player::initAnimations() 中直接传局部对象 Animation idleAnim; idleAnim.frame = 0; animations.add("idle", idleAnim);
这种方式存储的是对象副本,局部对象销毁后不影响map中的数据。
内容的提问来源于stack exchange,提问作者mswieboda
相关产品推荐
相关产品推荐

