Loki :: Factory在程序退出时抛出异常

时间:2013-09-02 07:41:44

标签: c++ loki vc8

我正在尝试在使用V​​C8编译的项目中使用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的提法。

如何解决问题?

2 个答案:

答案 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;
}