2016-10-28 4 views
4

Ich möchte geteilt ptr zuzugreifen, die in der Vereinigung ist, obwohl Segmentierungsfehler passiert:Gemeinsame ptr in Vereinigung

struct union_tmp 
{ 
    union_tmp() 
    {} 
    ~union_tmp() 
    {} 
    union 
    { 
     int a; 
     std::shared_ptr<std::vector<int>> ptr; 
    }; 
}; 

int main() 
{ 
    union_tmp b; 
    std::shared_ptr<std::vector<int>> tmp(new std::vector<int>); 
    b.ptr = tmp; //here segmentation fault happens 
    return 0; 
} 

Was ist der Grund eines Fehlers und wie kann ich es vermeiden?

+0

Dieser Code erzeugt keinen segfault – Rerito

+1

@Rerito: Dieser Code zeigt undefiniertes Verhalten. *Alles kann passieren. –

+3

Was wollen Sie hier eigentlich erreichen? Eine Vereinigung von einem int und einem shared_ptr ist ein ziemlich seltsames Biest. Das fühlt sich an wie ein [XY-Problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) –

Antwort

4

Sie müssen die std::shared_ptr innerhalb der Union initialisieren:

union_tmp() 
: ptr{} // <-- 
{} 

Andernfalls uninitialized ptr bleibt und Bediener löst seine Aufgabe ruft nicht definiertes Verhalten.

+3

Wahrscheinlich lohnt es sich, einen Kommentar hinzuzufügen, dass der Grund für den Fehler ist, dass 'b.ptr = tmp' den share_ptr-Kopierzuweisungsoperator aufruft, und das nimmt an, dass der shared_ptr bereits richtig ist initialisiert. –

+0

@MartinBonner Ich denke, explizite tut nicht weh. – Quentin

+0

Ich denke, dies als Antwort zu markieren ist falsch. Der OP-Code ist ein ungültiger C++ - Code, da er gegen die Einschränkungen verstößt, die der Standard den Gewerkschaften auferlegt. –

6

würde ich std::variant für eine sichere C++ verwenden "Gewerkschaften" (oder boost::variant wenn std::variant ist für Sie nicht verfügbar).

z. Sie können versuchen:

std::variant<int, std::shared_ptr<std::vector<int>>> v; 
v = std::make_shared<std::vector<int>>(); 
+0

@Default: Gern geschehen. –

+0

Ich bin mir nicht sicher, ob es gültig ist, die Klasse mit diesen Dingen als Mitglied zu verwenden. Es gibt ein Beispiel, wie man 'std :: string' und' std :: vector' als Mitglieder der Vereinigung benutzt. Es scheint, es ist gültig, aber sehr langweilig. Bitte korrigieren Sie meinen Fehler, danke. Lesen Sie hier: http://en.cppreference.com/w/cpp/language/union –

+0

@MarsonMao: Ich denke immer noch, Variante ist besser (sicherer, höheres Niveau, weniger Fehler/Bug anfällig). –