2013-09-02 22 views
0

Я пытаюсь использовать Loki::Factory в проекте, который скомпилирован с 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 файл «память». Исключением является нарушение прав доступа и стек начинается с:

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

Я не смог найти каких-либо ссылок на использование std::auto_ptr от Локи в Интернете.

Как решить эту проблему?

+2

Вы видите столбец в своем отладчике, где вызывается '~ auto_ptr'? Какое исключение выбрано? –

+0

Попробуйте добавить виртуальный деструктор в базовый класс. – user1837009

+0

@ user1837009 Добавление виртуального деструктора не помогает. Конечно, вы правы, так и должно быть. Я просто не сделал его виртуальным в примере –

ответ

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

Поскольку я всегда хотел посмотреть библиотеки Loki, я использовал этот шанс. Ну, для начала, проблема не связана с версиями MSVC, я запускал тот же пример в VS2008, а библиотеки Loki строятся с VS2008 и имеют те же результаты. Второй:

#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 удаляется, а затем после вызова деструктора фабрики то вызов erase на контейнер ассоциации терпит неудачу. Хорошо - если это не огромная сделка, не делайте завод глобальным объектом. Если это огромная сделка, попробуйте отладить и найти, почему Локи делает то, что он делает в atexit, может быть, вам нужно настроить что-то еще. Но, по крайней мере, насколько я вижу, это еще один плохой случай неопределенного поведения для уничтожения глобальных объектов.

EDIT: Loki Factory-Singleton throws "dead reference detected" in try-catch-block on ARM, макрос LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT может быть актуальным, так как я предположил бы, что вызывает destrcution, может быть, без этого объект будет не попасть в список объектов, разрушенных в atexit, но до сих пор, мои знания о библиотеках Локи не достаточно хорошо. Возможно, вам нужно определить политику жизненного цикла синглтона или что-то в этом роде.

+0

уже пытался LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT, не имеет значения –

+1

Да, я попробовал перестроить все решение Loki с этим макросом, даже если README заявляет 'Define LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT, чтобы избежать статического экземпляра/delete order problems'. –

+0

отправил решение в рамках вопроса. Вы были в основном правы! –