我正在尝试在使用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++
我找不到任何关于在互联网上使用Loki的std::auto_ptr
的提法。
如何解决问题?
答案 0 :(得分: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;
}
这很好用。我在你的例子中检查了崩溃,似乎Factory正在删除你创建的仿函数应该在它已经被销毁之后的关联容器。在我看来,这是因为Loki挂了atexit()
并删除了一些东西(不知道为什么,我想处理Singleton对象),这是你的Functor被删除的地方,然后是你的析构函数之后调用factory,然后对关联容器的erase
调用失败。好吧 - 如果这不是一个大问题,不要让工厂成为一个全球性的对象。如果这是一个大问题,尝试调试并找到为什么Loki正在做它在atexit
中做的事情,也许你需要设置更多东西。但至少据我所知,这是破坏全局对象的未定义行为的另一个坏例子。
编辑:Loki Factory-Singleton throws "dead reference detected" in try-catch-block on ARM,宏LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT可能是相关的,因为我猜它会触发强制攻击,也许没有这个,对象将不会进入atexit
中被破坏的对象列表,但仍然如此我对Loki图书馆的了解还不够好。也许你需要定义一个单身人士的生命周期政策或类似的东西。
答案 1 :(得分:0)
问题在于终身管理。我在这里报告解决方案以供参考:
#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;
}