2013-09-02 2 views
0

J'essaie d'utiliser Loki::Factory dans un projet qui est compilé avec VC8 (je ne suis pas autorisé à passer à un compilateur plus récent). Je vais avoir un problème lorsque le programme se termine, que je peux reproduis avec ce code de base (ce qui est le moins vous pouvez obtenir lors de l'utilisation d'une usine)Loki :: Factory lançant une exception à la sortie du programme

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

tout va bien jusqu'au moment où le système arrive à une pause demandant l'utilisation d'appuyer sur une touche (comme pour system("pause")); quand j'appuie sur la touche, cependant, le programme avorte, en raison d'une exception non gérée, lancée à partir de la fonction

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

qui se trouve dans le fichier visual studio « mémoire ». L'exception est une violation d'accès et la pile commence par:

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

Je ne pouvais trouver aucune référence à l'utilisation de std::auto_ptr de Loki sur Internet.

Comment le problème peut-il être résolu?

+2

Voyez-vous la callstack dans votre débogueur, forme où le '~ auto_ptr' est appelé? Quelle exception est lancée? –

+0

Essayez d'ajouter un destructeur virtuel à la classe de base. – user1837009

+0

@ user1837009 L'ajout du destructeur virtuel n'aide pas. Bien sûr, vous avez raison, ça devrait l'être. Je ne l'ai pas rendu virtuel dans l'exemple –

Répondre

0

Le problème est avec la gestion de la durée de vie. Je signale la solution ici pour la référence:

#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

Depuis que j'ai toujours voulu regarder les bibliothèques Loki j'ai utilisé cette chance. Eh bien, pour commencer, le problème n'est pas lié aux versions de MSVC, j'ai exécuté le même exemple sur les bibliothèques VS2008 et Loki avec VS2008 et j'ai eu les mêmes résultats. Deuxième:

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

Cela fonctionne très bien. J'ai examiné le crash à votre exemple et semble que l'usine supprime le conteneur d'association où le foncteur que vous avez créé est supposé être après qu'il est déjà détruit. Il me semble que c'est parce que Loki connecte atexit() et y supprime des choses (je ne sais pas pourquoi, j'imagine gérer des objets Singleton), c'est là que votre Functor est supprimé, et après que le destructeur de votre usine est appelé et puis l'appel erase sur le conteneur d'association échoue. Eh bien, si ce n'est pas une affaire énorme, ne faites pas de l'usine un objet global. Si c'est un gros problème, essayez de déboguer et de trouver pourquoi Loki fait ce qu'il fait dans atexit, peut-être que vous avez besoin de configurer quelque chose de plus. Mais au moins autant que je puisse voir, c'est un autre mauvais cas de comportement non défini pour la destruction des objets globaux.

EDIT: Loki Factory-Singleton throws "dead reference detected" in try-catch-block on ARM, la LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT macro pourrait être pertinente, car je suppose que déclenche la destrcution, peut-être sans que cela l'objet ne sera pas obtenir dans la liste des objets détruits dans atexit mais encore, mes connaissances sur les bibliothèques Loki n'est pas assez bien. Peut-être que vous avez besoin de définir une politique de durée de vie du singleton ou quelque chose comme ça.

+0

déjà essayé LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT, n'a pas fait de différence –

+1

Ouais, j'ai essayé de reconstruire toutes les solutions Loki avec cette macro, pas bien, même si README indique 'Définir LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT pour éviter l'instanciation statique/supprimer les problèmes de commande ». –

+0

a posté la solution dans la question. Vous étiez fondamentalement juste! –

Questions connexes