gpt4 book ai didi

c++ - 共享所有权双重自由错误

转载 作者:搜寻专家 更新时间:2023-10-31 01:04:40 24 4
gpt4 key购买 nike

我有一个引擎类,它包含并拥有一些系统。 Engine 类有两个容器,一个 map 和一个 vector 。两者都保留指向系统的指针。

addSystem 模板函数应在映射中添加所需类型的新系统的指针,而 addToPipeline 应在 vector 中添加作为参数传递的系统指针。我为此使用了 shared_ptr,但我做错了什么,因为如果我使用 addToPipeline 函数,我会得到双重释放错误。

这是简化的引擎类:

class Engine
{
public:

template <class T>
T& addSystem();

void addToPipeline(System&);

private:
std::map<std::type_index, std::shared_ptr<System>> m_systems;
std::vector<std::shared_ptr<System>> m_pipeline;
};


void Engine::addToPipeline(System& sys)
{
m_pipeline.push_back(std::shared_ptr<System>(&sys));
}


template <class T>
T& Engine::addSystem()
{
std::shared_ptr<T> system = std::make_shared<T>();
auto inserted = m_systems.emplace(typeid(T),system);
return static_cast<T&>(*(*inserted.first).second);
}

函数应该像下面这样使用:

auto& POSITION_SYSTEM = engine.addSystem<PositionSystem>();
engine.addToPipeline(POSITION_SYSTEM);

感谢任何帮助!

最佳答案

在这一行中:

m_pipeline.push_back(std::shared_ptr<System>(&sys));

您正在为一个已经托管的对象创建一个 shared_ptr,因为您已经将同一个对象包装在另一个智能指针中。因此,对于同一个对象,您最终得到 两个 引用计数,因此您获得了双重释放。

shared_ptr 不应该这样使用。相反,您应该从 addSystem 返回一个 shared_ptr 并将其中一个作为 addToPipeline 的参数:

void Engine::addToPipeline(std::shared_ptr<System> sys)
{
m_pipeline.push_back(sys);
}


template <class T>
std::shared_ptr<T> Engine::addSystem()
{
std::shared_ptr<T> system = std::make_shared<T>();
m_systems.emplace(typeid(T),system);
return system; // No need to use the return value of emplace
}

shared_ptr 的想法是,您始终传递 shared_ptr 而不是使用裸指针或引用(除非所有权无关紧要 - 那么您也可以传递一个引用)。您必须这样做,因为引用计数器由智能指针管理。

编辑:正如 rozina 所指出的:当然,只要没有人试图删除相应的地址,您仍然可以传递对托管对象的引用。如果其他代码对使用某个对象感兴趣但不关心所有权,这实际上可能更可取。例如,您可能希望拥有一个公共(public)接口(interface),该接口(interface)允许获取对内部由智能指针管理的某个对象的引用。例如:

class Foo {
public:
Bar& getBar() {
return *m_bar;
}
private:
std::shared_ptr<Bar> m_bar;
};

只要没有人执行 delete &aFoo.getBar() 就完全没问题 - 如果您使用该引用创建一个新的 shared_ptr 就会发生这种情况,就像您在原始代码。

关于c++ - 共享所有权双重自由错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23470942/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com