- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个引擎类,它包含并拥有一些系统。 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/
这是我正在调试的函数: boolean adin_memory(char* buffer, int size_chunck, int end_flag){ global_buffer = my
我正在尝试为具有自由 float 底座的机器人计算末端执行器空间速度雅可比行列式。由于自由 float 基数,雅可比应该包含一个基数组件和一个操纵器注释(参见 https://spart.readth
procedure FreeListObjects( l : TStrings); var i : integer; BEGIN FOR i := 0 TO l.Count -1 DO BEG
我正在探索 Haskell 中的选项,这些选项可以让我将业务逻辑与底层系统的技术实现分开。例如,在 Web 服务器的上下文中,将 Web 服务器处理其接收的信息的方式与其读取和写入数据库的方式分开。要
我的目标是使用来自 ActiveMQ 的 WebSphere Liberty Appserver(完整的 Java EE 标准)使用消息。不幸的是,我不知道如何配置 WebSphere Liberty
我以这种方式分配了一个非方阵,但我不确定我是否正确使用了释放 float **matrix_alloc(int m /* rows */, int n /* columns */) { int
我在阅读 refuting the notion 之后的第 13.5 节内置运算符不参与重载决议,并注意到没有关于 operator->* 的部分。它只是一个通用的二元运算符。 它的兄弟operato
我正在尝试使用 Libelf 库来获取有关某些 elf 文件的一些信息。但我不断收到这些“对 [...] 的 undefined reference ”。我从 synaptic 安装了 libelf(
我有创建动态结构数组的波纹管代码。 #include #include #include typedef struct { int flag; char* ip; } ip_mo
我是 StackOverflow 的新人。我现在正在学习C指针。 这是我的代码: #include #include int alloc(int* p){ p = (int*) mallo
我是 StackOverflow 的新人。我现在正在学习C指针。 这是我的代码: #include #include int alloc(int* p){ p = (int*) mallo
我正在用 C 编写一个程序,我需要读入一个文件并打印出每个至少 4 个字符长的字符串。我在分配要使用的内存时遇到问题。字符串可以任意长。我试图将缓冲区分配给文件的大小,然后在最后释放它,但我显然错过了
我尝试用 C 语言编写 ls 命令,但 -R 选项有问题。 输出: /Applications/Atom.app/Contents/Resources/app/apm/node_modules/es5
我正在编写一个 shell,但在执行内存检查时遇到问题,因为 valgrind 无法正常运行。 我遇到了这样的错误(我自己杀死了它): ==19703== Memcheck, a memory err
我有这样一段代码: void *write_parallel(void *num_for_chunk) { struct rusage *sum = (struct rusage*) mall
当使用包含 200-300 个整数(以空格分隔)的输入 .txt 文件运行此代码时,我在使用 fprintf 语句的 for 循环之前收到错误。 我不确定 qsort 是否导致了此错误或为什么会发生此
我试图告诉 Websphere Liberty 我的 log4j2.xml 文件在哪里,但它不起作用。 在我的文件 jvm.options 中,我配置: -Dlog4j.configurationFi
从 websphere liberty 16 迁移到 19.0.0.1 我遇到以下异常:运行存储过程后关闭连接,出现以下异常: EJB threw an unexpected (non-declare
当对大小为 210*8 的种子数据集运行此代码时,我在预测函数中的 qsort() 行之后收到错误。它不在 qsort() 之后执行。 我不确定 qsort 是否导致了此错误或为什么会发生此错误,但如
这个问题已经有答案了: Facing an error "*** glibc detected *** free(): invalid next size (fast)" (2 个回答) 已关闭 9
我是一名优秀的程序员,十分优秀!