Loki::Factory 在程序退出时抛出异常
Posted
技术标签:
【中文标题】Loki::Factory 在程序退出时抛出异常【英文标题】:Loki::Factory throwing an exception on program exit 【发布时间】:2013-09-05 06:04:10 【问题描述】:我正在尝试在使用 VC8 编译的项目中使用 Loki::Factory
(我不允许切换到较新的编译器)。当程序退出时我遇到了一个问题,我可以用这个基本代码重现它(这是你在使用工厂时可能想要实现的最起码)
#include "stdafx.h"
#include <loki/Factory.h>
struct Base;
Loki::Factory< Base, int> factory;
struct Derived : public Base;
Base* buildDerived()
return new Derived();
namespace
bool registeredD = factory.Register(1, buildDerived);
int _tmain(int argc, _TCHAR* argv[])
system("pause");
return 0;
一切都很好,直到系统暂停要求使用按键(如system("pause")
);但是,当我按下该键时,由于从函数内部抛出未处理的异常,程序中止
~auto_ptr()
// destroy the object
delete (_Ty *)_Myptr;
可以在 Visual Studio 文件“memory”中找到。异常是访问冲突,堆栈开始于:
compmgr.dll!std::auto_ptr<Loki::FunctorImpl<Interface2D::IElement *,Loki::NullType,Loki::SingleThreaded> >::~auto_ptr<Loki::FunctorImpl<Interface2D::IElement *,Loki::NullType,Loki::SingleThreaded> >() Riga 718 + 0x32 byte C++
compmgr.dll!Loki::Functor<Interface2D::IElement *,Loki::NullType,Loki::SingleThreaded>::~Functor<Interface2D::IElement *,Loki::NullType,Loki::SingleThreaded>() + 0x2b byte C++
我在 Internet 上找不到 Loki 使用 std::auto_ptr
的任何参考。
如何解决问题?
【问题讨论】:
您是否在调试器中看到调用堆栈,在调用~auto_ptr
的位置?抛出哪个异常?
尝试将虚拟析构函数添加到基类。
@user1837009 添加虚拟析构函数没有帮助。你当然是对的,应该是这样。我只是没有在示例中将其设为虚拟
【参考方案1】:
因为我一直想看看 Loki 库,所以我利用了这个机会。好吧,首先,这个问题与 MSVC 版本无关,我确实在 VS2008 上运行了相同的示例,并且使用 VS2008 构建的 Loki 库得到了相同的结果。第二:
#include "stdafx.h"
#include <loki/Factory.h>
#pragma comment(lib, "loki_D.lib")
struct Base;
struct Derived : public Base;
Base* buildDerived()
return new Derived();
int _tmain(int argc, _TCHAR* argv[])
Loki::Factory< Base, int> factory;
bool registeredD = factory.Register(1, buildDerived);
//system("pause");
return 0;
这很好用。我在您的示例中检查了崩溃,似乎工厂正在删除关联容器,您创建的仿函数应该在它已经被销毁之后所在的位置。在我看来,这是因为 Loki 正在连接 atexit()
并在那里删除一些东西(不知道为什么,我猜是为了处理 Singleton 对象),这就是你的 Functor 被删除的地方,然后在你工厂的析构函数之后调用,然后对关联容器的erase
调用失败。好吧 - 如果不是什么大不了的事,不要让工厂成为全局对象。如果这很重要,请尝试调试并找出 Loki 为何会像在 atexit
中所做的那样,也许您需要进行更多设置。但至少在我看来,这是另一个破坏全局对象的未定义行为的坏情况。
编辑:Loki Factory-Singleton throws "dead reference detected" in try-catch-block on ARM ,宏 LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT 可能是相关的,因为我猜这会触发破坏,也许没有这个,对象将不会进入 atexit
中破坏的对象列表中,但我仍然了解 Loki图书馆还不够好。也许您需要定义单例的生命周期策略或类似的东西。
【讨论】:
已经尝试过 LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT,没有任何作用 是的,我尝试使用该宏重建所有 Loki 解决方案,但不好,即使 README 声明Define LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT to avoid static instantiation/delete order problems
。
在问题中发布了解决方案。你基本上是对的!
是的,我一路上看到了 SingletonHolder 模板,但由于我对 Loki 缺乏了解,所以没有深入了解。没有它它仍然很奇怪。【参考方案2】:
问题在于生命周期管理。我在这里报告解决方案以供参考:
#include "stdafx.h"
#include <loki/Factory.h>
#include <loki/Singleton.h>
struct Base
virtual ~Base();
;
typedef Loki::SingletonHolder< Loki::Factory<Base, int> > Factory;
struct Derived : public Base;
Base* buildDerived()
return new Derived();
namespace
bool registeredD = Factory::Instance().Register(1, buildDerived);
int _tmain(int argc, _TCHAR* argv[])
system("pause");
return 0;
【讨论】:
以上是关于Loki::Factory 在程序退出时抛出异常的主要内容,如果未能解决你的问题,请参考以下文章
Gradle 在从网络下载工件时抛出错误.. 异常:Gradle 任务 assembleDebug 失败,退出代码为 1