Zeiger von anderer Klasse in einer abstrakten Klasse löschen



  • Hallo!
    Hab folgendes Problem:
    Ich habe in einer abstrakten Klasse Variable einen Verweis auf eine andere Klasse Type:

    class variable
    {
    public:
    	virtual ~variable();	//added
    	// Print function
    	virtual void Print(std::ostream & os) const =0;
    protected:
    	std::string mName;
    	std::string mType;
    	Type* mpType; -> hier liegt das Problem
    };
    

    wenn ich im virtuellen Destruktor den mpType delete, dann stürzt das Programm ab. eh klar weil ichs ja in den abgeleiteten Klassen eigentlich benutze. nur wenn ich dort im delete den mptype lösche (klasse javavariable und iecvariable) stürzt das programm genauso ab. habe jetzt was im internet was von shared pointers gelsen. allerdings haben wir das nie gelernt und die erklärungen auf englisch sind mir irgendwie nicht geheuer.

    mfg
    ACnut



  • ACnut schrieb:

    wenn ich im virtuellen Destruktor den mpType delete, dann stürzt das Programm ab. eh klar[...]

    OK, mir nicht. Wieso stürzt das Programm ab?



  • hier ist mal das klassendiagramm (das tba und so könnt ihr einfach wegdenken, es ist die alte version. in dem symbolparser sind zwei listen aus variable* und type* drinnen,...):
    http://www.imagenetz.de/f43f8701b/Unbenannt.png.html

    @Bashar ich hab mir das so erklärt:
    hab ja eine liste aus typen (z.b int). wenn ich jetz zwei variablen hätte (int a und int b), wenn ich jetzt die variable int a lösche dann happerts ja mit int b oder nicht?

    dieser leak ist anscheinend so arg, dass sogar der visual leak detector abkratzt. (ohne delete krieg ich nur einen memory leak und dieser kommt eben von diesem mptype pointer).

    also wie muss ich das problem angehen?



  • Wenn ich das jetzt richtig verstehe:
    Die Klasse variable (bzw. die abgeleiteten Klassen) verwaltet alle Variablen eines Typen, richtig?
    Und wenn der Destruktor Verwaltungsdaten löscht, bevor die zu verwaltenden Variablen gelöscht werden, crasht das Programm?
    Einfache Lösung: Dafür sorgen, dass der Destruktor erst aufgerufen wird, wenn alle Variablen weg sind.



  • nicht direkt
    im symbolparser haben wir eine methode addvariable

    void AddVariable(std::string const& name, std::string const& type);
    

    dieses type string wird einer funktion search übergeben der dann in der typeliste danach sucht

    @Nathan:
    Einfache Lösung: Dafür sorgen, dass der Destruktor erst aufgerufen wird, wenn alle Variablen weg sind.

    wie sorgt man dafür?



  • Variante 1: Typen nie löschen. Leakt, klar. Ist nur die Frage ob es ne Rolle spielt dass es leakt. Natürlich ist es immer doof wenn beim Beenden des Programms Leaks gemeldet werden, aber das kann man u.U. gezielt für die Stellen ausschalten wo eben die Typen ge new t werden. (Zumidnest für den MSVC Debug-Heap kann man das machen, die nötige Funktion heisst _CrtSetDbgFlag .

    Variante 2: Mach ne Klasse die die ganzen Type-Objekte "besitzt", und sorg dafür dass dieses Type-Objekte-Besitzerobjekt erst nach allen Variablen-Objekten gelöscht wird. Irgendwo musst du ja sowieso schon ne Liste aller Typen haben, sonst kannst du die ja unmöglich nachschlagen (nen String in nen Type* verwandeln). EDIT: ja, hast du auch, nämlich deine "typeliste" /EDIT
    Genau der Klasse die diese Liste/Map hat könntest du die Verantwortung umbinden alle Typen zu löschen.
    (Aber natürlich nur, wenn das Objekt dieser Klasse auch erst gelöscht wird nachdem alle Variablen Objekte gelöscht wurden.)

    Variante 2.1: Pack die Typen in einen besitzenden Container. z.B. Boost ptr_map . Dann musst du dich um die Freigabe nicht explizit kümmern. Bzw. falls Type nicht polymorph ist, dann tut es sogar ne std::map .

    Variante 3: Verwende shared_ptr<Type> statt Type* . Dann wird der Type automatisch dann gelöscht, wenn der letzte shared_ptr<Type> verschwindet der auf diese Type Instanz zeigt.



  • von wo muss ich diesen boost.h holen damit ich das mit dem unique_ptr überhaupt benutzen kann?
    weil wenn ich das header von diesem bsp laden will gehts natürlich nicht 🙂
    http://www.c-plusplus.net/forum/134971-full



  • Boost besteht aus etwas mehr als nur einem Header-File. Inklusive Doku, Unit-Tests etc. sind es zigtausend Files.
    Und runterladen kannst du das Ding auf boost.org. Hättest du aber in 5 Sekunden selbst rausgefunden - "Boost C++" in Google eintippen reicht (ohne die "").



  • dachte, dass man das aus den libraries iwo rauskopieren muss 🙂
    vielen dank nochmal für die hilfe 🙂



  • ACnut schrieb:

    von wo muss ich diesen boost.h holen damit ich das mit dem unique_ptr überhaupt benutzen kann?

    Für unique_ptr<> brauchst Du kein Boost, ist Teil von C++11.



  • Wobei ich nicht weiss wozu man unique_ptr her einsetzen sollte.
    OK, ja, map<string, unique_ptr<T>> ginge vermutlich.


Anmelden zum Antworten