2015-06-25 8 views
5

Ho un'applicazione C++ che utilizza l'ereditarietà e il polimorfismo multipli. Funziona correttamente su x86_64-linux ma su arm-linux sto riscontrando un errore di segmentazione.Compilazione incrociata ARM, errore di segmentazione su ereditarietà multipla

Ho scritto un semplice test per ricreare il problema:

#include <list> 
#include <iostream> 

class SmartObject 
{ 
    public: 

    // removing this destructor makes it work in ANY way 
    virtual ~SmartObject(){ 
    } 

    void method(void) {} 
}; 

class IMyInterface 
{ 
    public: 

    // removing this destructor have no effect (fails) 
    virtual ~IMyInterface(){ 
    } 

    virtual std::list<int> getList() = 0; 
}; 

class MyObject : public SmartObject, public virtual IMyInterface 
{ 
    public: 

    MyObject() 
    { 
     list.push_back(4); 
     list.push_back(5); 
    } 

    virtual std::list<int> getList() { 
     return list; 
    } 

    std::list<int> list; 
}; 

int main() 
{ 
    IMyInterface * ip = new MyObject(); 
    std::list<int> list_clone = ip->getList(); 
    std::cout << list_clone.size() << std::endl; 
    delete ip; 
    return 0; 
} 

Questo codice funziona correttamente su x64-linux e Win32 (anche su altre piattaforme embedded), ma sul braccio-linux provoca un errore di segmentazione quando si chiama list_clone.size() perché l'elenco copiato ha un puntatore di coda errato.

Ho provato con gcc 4.8.3 e 4.9.1 ma ho visto lo stesso comportamento. L'architettura di destinazione è ARM cortex-A processori con hard floating point.

Qualche idea?

realtà ho trovare due modi indipendenti per farlo funzionare:

  1. rimuovendo il distruttore SmartObject, ma questo non è fattibile sul l'applicazione complessiva.
  2. dichiarando MyObject in questo modo (virtuale su SmartObject e ordine invertito):

class MyObject : public virtual IMyInterface, public virtual SmartObject

Grazie in anticipo

+0

Nel costruttore 'MyObject()', non è necessario chiamare i costruttori della classe base? –

+0

Penso che siano implicitamente chiamati essere il compilatore. Ad ogni modo l'errore di segmentazione accade anche aggiungendo costruttori in IMyInterface e SmartObject e chiamandoli esplicitamente (ho appena provato). – ingram

risposta

-1

Avrete anche bisogno di un distruttore virtuale per class MyObject. Altrimenti non ci si può aspettare di distruggere correttamente un'istanza MyObject attraverso un puntatore del tipo IMyInterface.

+0

Io non la penso così (se non hai bisogno di distruggere nulla non hai bisogno di un distruttore). Inoltre, l'errore di segmentazione si verifica prima della distruzione dell'oggetto. Tuttavia ho provato e non rimuove il difetto di segmentazione. Grazie lo stesso. – ingram