main函数中访问shared_ptr向量对象异常问题求助
问题分析与解决方案
嘿,我一眼就揪出你遇到的问题根源了——参数传递方式错误导致的副本失效问题!
问题出在哪?
你写的turnOrder函数里,第三个参数std::vector<std::shared_ptr<Unit>> Units是值传递的。这意味着当你在main里调用turnOrder(monsters, heroes, Units)时,函数会创建一个main中Units向量的独立副本,你在函数内部对这个副本做的所有添加元素操作,都不会影响到main里的原始向量。
所以函数内部测试时,你操作的是那个临时副本,自然能看到正确的输出;但函数执行完毕后,这个副本就被销毁了,main里的Units还是空的——这时候你去访问Units[0],直接触发了内存访问违规错误(也就是你看到的exit code -1073741819 (0xC0000005))。
怎么解决?
只需要把Units参数改成引用传递,让函数直接操作main里的原始向量就行。另外,为了性能优化,monsters和heroes如果不需要修改的话,也建议改成const引用,避免不必要的拷贝开销。
修改后的函数签名应该是这样:
void turnOrder( const std::vector<std::shared_ptr<Monster>>& monsters, const std::vector<std::shared_ptr<Hero>>& heroes, std::vector<std::shared_ptr<Unit>>& Units) {
修改后的完整代码示例
#include <vector> #include <memory> #include <algorithm> // 假设你已经定义了基础类结构 class Unit { public: virtual void printOut() = 0; virtual void findSpeedRate() = 0; int speedRate = 0; }; class Monster : public Unit { public: void printOut() override {} void findSpeedRate() override {} }; class Hero : public Unit { public: void printOut() override {} void findSpeedRate() override {} }; class Crusader : public Hero { public: Crusader(int) {} }; void turnOrder( const std::vector<std::shared_ptr<Monster>>& monsters, const std::vector<std::shared_ptr<Hero>>& heroes, std::vector<std::shared_ptr<Unit>>& Units) { std::vector<std::shared_ptr<Unit>> units; units.reserve(8); units.insert(units.begin(), heroes.begin(), heroes.end()); units.insert(units.end(), monsters.begin(), monsters.end()); // TESTING INITIAL VECTOR for(int i = 0; i < units.size(); i++){ units[i]->printOut(); } for (int i = 0; i < units.size(); i++) { units[i]->findSpeedRate(); } struct X{ inline bool operator() ( const std::shared_ptr<Unit> obj1, const std::shared_ptr<Unit> obj2){ return(obj1->speedRate > obj2->speedRate); } }; std::sort(units.begin(), units.end(), X()); for(int i = 0; i < units.size(); i++){ Units.emplace_back(units[i]); } // TESTING ORDERED VECTOR for(int i = 0; i < Units.size(); i++){ Units[i]->printOut(); } } int main(){ std::vector<std::shared_ptr<Unit>> Units; std::vector<std::shared_ptr<Monster>> monsters; std::vector<std::shared_ptr<Hero>> heroes; auto crusader1 = std::make_shared<Crusader>(1); heroes.emplace_back(crusader1); // 添加其他怪物和英雄对象的逻辑 turnOrder(monsters, heroes, Units); Units[0]->printOut(); // 现在可以正常访问了 }
额外小贴士
- 以后遇到类似“函数内修改容器但外部没变化”的问题,先检查参数是不是值传递,大概率是这个原因。
- 使用const引用传递不需要修改的参数,是C++里的最佳实践之一,能有效避免不必要的拷贝开销。
内容的提问来源于stack exchange,提问作者nyan
相关产品推荐
相关产品推荐

