2016-09-07 3 views
0

Nach ein paar Tagen der Verzögerung dieser Frage und Debugging habe ich festgestellt, dass Wenn mein Code unten nach dem Entfernen der Vektor aus der Union (und den gesamten Code ausgeführt wird Erwähnung dieses Vektors) das seg. der Fehler verschwindet.Seg. Fehler beim Beenden durch Zeiger auf Vektor der Zeiger auf struct

#include <string> 
#include <vector> 
#include <functional> 

struct Task 
{ 
    std::string Name; 

    std::vector<Task*> *Subtasks; 
    std::function<void(std::string const &)> Job; 

    Task() {} 
    Task(std::string const &arg_0) { Name = arg_0; } 
    Task(std::string const &arg_0, std::vector<Task*> *arg_1) { Name = arg_0; Subtasks = arg_1; } 
    Task(std::string const &arg_0, std::function<void(std::string const &)> arg_1) 
    { Name = arg_0; Job = arg_1; } 

    ~Task() { for (auto tItem : *Subtasks) { delete tItem; } } 
}; 

class Console 
{ 
private: 
    std::vector<Task*> Routine; 

public: 
    ~Console() { for (auto tItem : Routine) { delete tItem; } } //I thought that this is not needed but Valgrind thinks otherwise, strangely the deconstructors of the Tasks are not called, I guess. 

    void add(Task *arg_0) { Routine.push_back(arg_0); } 

    void foo() 
    { 
    Task *tTask = new Task(); 
    //Task *tTask = new Task("Name"); 
    //Task *tTask = new Task("Name", [this](std::string const &arg_0){ ; }); 
    //Seg. fault still remains. 
    add(tTask); 
    } 
}; 

int main() 
{ 
    Console _Console; 
    _Console.foo(); 
} 

For quick online IDE code test


Dies sollte wohl eine andere Frage, aber ich denke, es ist zu einfach ist. Ich habe schon früher gehört, dass, wenn ein Nicht-Trivial in einer Union verwendet wird, sollte darauf geachtet werden, wenn die Werte geschaltet werden, wie würde man das tun, und ist es notwendig, wenn ich keinen Wert haben will ändert sich zur Laufzeit?

EDIT1

die Vereinigung von Vektor- und std entfernt :: function

EDIT2

Die Seg. Der Fehler wird höchstwahrscheinlich vom Dekonstruktor verursacht ~ Task();.

+3

Zwischen dem Ignorieren der Regel von 5/3/0 und dem undefinierten Verhalten bei der Handhabung Ihrer "Union" würde ich sagen, Sie haben einige Probleme, Sohn. –

+0

Was ist der Zweck der Gewerkschaft? Versuchen Sie, ein wenig Platz zu sparen? – NathanOliver

+1

'Job = arg_1' setzt Junk im Zeiger in' Subtasks' und stürzt beim Löschen ab. –

Antwort

1

Wenn dieser Konstruktor aufgerufen wird:

Task(std::string const &arg_0, std::function<void(std::string const &)> arg_1) 
{ Name = arg_0; Job = arg_1; } 

dann stürzt es sicher, wenn destructor da aufgerufen wird Subtasks nicht initialisiert wird.

~Task() { for (auto tItem : *Subtasks) { delete tItem; } } 

Fix:

Task(std::string const &arg_0, std::function<void(std::string const &)> arg_1) 
{ Name = arg_0; Job = arg_1; Subtasks = nullptr;} 

~Task() { if (Subtasks!=nullptr) for (auto tItem : *Subtasks) { delete tItem; } } 

und (thx für die Kommentare) sammeln/ersetzen und alle anderen Konstrukteuren wie dieses Problem zu beheben:

Task(std::string const &arg_0 = "", std::vector<Task*> *arg_1 = nullptr) { Name = arg_0; Subtasks = arg_1; } 

Nach einiger Diskussion, scheint es, dass es eine möglicher Designfehler im Code der Frage: das Löschen des Inhalts des Vektors ist gefährlich, da die Zeiger möglicherweise noch von anderen Clients verwendet werden oder nicht einmal zugewiesen wurden, sondern nur auf lokale va verweisen Versprechungen. Und warum Subtasks ist ein Zeiger an erster Stelle? Warum nicht löschen?

+0

In [seinem ideone.com-Beispiel] (http://ideone.com/i0p8jd) ruft er den Standardkonstruktor auf. Es muss auch "Unteraufgaben" initialisieren. –

+0

zu viele Konstruktoren, Platz für Fehler, bearbeitet thx. –

+0

Das Suchen nach 'nullptr' wird nicht benötigt, da das Löschen von' nullptr' absolut sicher ist –

Verwandte Themen