You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 15:12:41