c++c++-lokivc8

Loki::Factory throwing an exception on program exit


I'm trying to use Loki::Factory in a project which is compiled with VC8 (I'm not allowed to switch to a newer compiler). I'm having an issue when the program exits, which I can reproduce with this basic code (which is the very least you might want to achieve when using a 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;
}

everything is fine up to when the system gets to a pause asking for the use to press a key (as for system("pause")); when I press the key, however, the program aborts, because of an unhandled exception, thrown from within the function

~auto_ptr()
{   // destroy the object
delete (_Ty *)_Myptr;
}

which can be found in the visual studio file "memory". The exception is an access violation and the stack starts with:

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++

I couldn't find any reference to the use of std::auto_ptr from Loki on the internet.

How can the problem be solved?


Solution

  • The problem is with lifetime management. I report the solution here for reference:

    #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;
    }