Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Segmentation fault lub Illegal instruction przy własnej implementacji boost::any

Ostatnio zmodyfikowano 2014-07-28 09:46
Autor Wiadomość
kubawal
Temat założony przez niniejszego użytkownika
Segmentation fault lub Illegal instruction przy własnej implementacji boost::any
» 2014-07-27 18:57:30
Piszę własny system eventów do sfml i potrzebuję miejsca na 'dane użytkownika', czyli po prostu dowolne dane.
Jednak przy wywoływaniu destruktora debugger wyrzuca SIGSEGV albo SIGILL
C/C++
class LLIB_API AnyData
{
    struct LLIB_API DataBase
    {
        virtual ~DataBase() { }
        virtual DataBase * clone() = 0;
    };
   
    template < typename DataT >
    struct LLIB_API Data
        : public DataBase
    {
        DataT data;
        using dataT = DataT;
       
        Data( const Data < DataT >& d )
            : data( d.data )
        { }
        Data( const DataT & d )
            : data( d )
        { }
       
        template < typename T >
        T get() { assert( typeid( DataT ) == typeid( T ) ); return data; }
       
        template < typename T >
        void set( const T & t ) { assert( typeid( DataT ) == typeid( T ) ); data = t; }
       
        virtual DataBase * clone() { return new Data < DataT >( * this ); }
    };
   
    DataBase * db;
    String ti;
   
public:
    AnyData()
        : db( NULL )
         , ti( "" )
    { }
    template < typename T >
    AnyData( const T & t )
        : db( new Data < T >( t ) )
         , ti( typeid( T ).name() )
    { }
    ~AnyData() { if( db ) { delete db; } } // <- tutaj wywala SIGSEGV
   
    AnyData( const AnyData & ad )
        : ti( ad.ti )
    { db = ad.db->clone(); }
    AnyData & operator =( const AnyData & ad ) { if( db ) delete db; ti = ad.ti; db = ad.db->clone(); return * this; }
   
    template < typename T >
    void set( const T & t ) { if( ti == typeid( T ).name() && db ) dynamic_cast < Data < T >*>( db )->set < T >( t );
        else { if( db ) delete db; db = new Data < T >( t ); ti = typeid( T ).name(); } }
   
    template < typename T >
    T get() const { assert( db && typeid( T ).name() == ti ); return(( Data < T >* ) db )->get < T >(); }
};

//...

struct LLIB_API Event // <- albo tutaj SIGILL
{
    String msg;
    Window * emmiter;
    AnyData data;
   
    template < typename DataT >
    Event( const char * msg, const DataT & data = DataT(), Window * emmiter = NULL )
        : msg( msg )
         , emmiter( emmiter )
         , data( data )
    { }
    Event()
        : emmiter( NULL )
    { }
};

Próbowałem użyć zwykłego boost::any, ale wtedy wyrzuca mi w logu debuggera:
Invalid Address specified to RtlFreeHeap( 003F0000, 003F6F70 )
P-114478
pekfos
» 2014-07-27 19:15:47
Podaj więcej kodu, lub przypadek użycia powodujący błąd.
P-114479
kubawal
Temat założony przez niniejszego użytkownika
» 2014-07-27 19:57:38
Event działą normalnie, jednak zawsze, kiedy wywołuje się destruktor ~AnyData() pojawia się błąd.
P-114483
unkn9wn
» 2014-07-27 20:09:40
To zabezpieczenie
if( db ) delete db;
nie działa.

Zdaje mi się, że gdzieś dwa razy wywołujesz delete na tym samym wskaźniku

jeżeli rzeczywiście potrzebujesz wskaźnika, sprawdź może std::unique_ptr
P-114487
kubawal
Temat założony przez niniejszego użytkownika
» 2014-07-28 09:46:24
Problem rozwiązany, po prostu program wczytywał starą dll'kę zamiast nowej i mu się coś nie zgadzało :)
P-114512
« 1 »
  Strona 1 z 1