Probleme mit std::list...::iterator
-
Hallo zusammen ich habe ein kleines Problem mit dem, bei mir eingesetzten Befehl
std::list<Tree<T>*>::iterator
hier der Quellcode:
main2.cpp
#include <stdlib.h> #include "main2.h" template<class T> Tree<T>::Tree(T* element) : element(&element) { leaf = true; } template<class T> Tree<T>::~Tree() { if(!leaf) { for (std::list<Tree<T>*>::iterator it = child.begin(); it != child.end(); it++) { *it.~Tree(); } } for (std::list<Tree<T>*>::iterator it = parent.begin(); it != parent.end(); it++) { *it.deletechild(this) } delete this; } template<class T> T* Tree<T>::getelement() { return *this.element; } template<class T> bool Tree<T>::deletechild(Tree<T>* tokill) { for (std::list<Tree<T>*>::iterator it = child.begin(); it != child.end(); it++) { if( tokill == it){ child.erase(it); return true; } } // Error code hier einfügen return false; } template<class T> bool Tree<T>::makeparent (Tree<T>* newParent){ if (*newParent.makechild(this)){ parent.push_back(newParent); return true; } else{ //Error code hier einfügen return false; } } template <class T> void Tree<T>::makenewchild(){ child.push_back(new Tree<T>); } template<class T> bool Tree<T>::makechild(Tree<T>* inTree) { child.push_back(inTree); return true; }
und dann noch die main2.h
#include <iostream> #include <list> /** * */ template<class T> class Tree { private: T* element; public: std::list<Tree<T>*> child; std::list<Tree<T>*> parent; Tree(T*); ~Tree(); bool makechild(Tree<T>*); bool deletechild(Tree<T>*); bool makeparent(Tree<T>*); void makenewchild(); T* getelement(); bool leaf; };
ich bekomme da immer eine Reihe an Fehlern raus... (für jede "for" schleife)
/home/evd/main2.cc: In destructor ‘Tree<T>::~Tree()’: /home/evd/main2.cc:15:8: error: need ‘typename’ before ‘std::__cxx11::list<Tree<T>*>::iterator’ because ‘std::__cxx11::list<Tree<T>*>’ is a dependent scope for (std::list<Tree<T>*>::iterator it = child.begin(); it != child.end(); it++) ^~~ /home/evd/main2.cc:15:38: error: expected ‘;’ before ‘it’ for (std::list<Tree<T>*>::iterator it = child.begin(); it != child.end(); it++) ^~ /home/evd/main2.cc:15:58: error: ‘it’ was not declared in this scope for (std::list<Tree<T>*>::iterator it = child.begin(); it != child.end(); it++) ^~ /home/evd/main2.cc:15:58: note: suggested alternative: ‘int’ for (std::list<Tree<T>*>::iterator it = child.begin(); it != child.end(); it++) ^~ int
Ich muss gestehen ich stehe etwas auf dem Schlauch... die Liste ist doch vom Typ Tree<T>* ... und warum will er das vor dem std:: haben
wehre nett wenn ihr mir einen Ansatz geben könntet
Grüße EvD
-
Benutze auto it = child.begin().
Wie kommst du auf die Idee den Tree Destruktor aufzurufen?
Wie kommst du auf die Idee delete this im Destruktor aufzurufen?
-
Faustregel: templates werden im Header implementiert.
-
Hallo
Ich habe den Fehler jetzt so wie du es gesagt hast mit Auto korrigiert ... aber verstehe ich leider immer noch nicht was an meinem falsch war ...
Jetzt zu dem was manni66 noch gesagt hast:
manni66 schrieb:
Wie kommst du auf die Idee den Tree Destruktor aufzurufen?
Habe ich jetzt auch geendert... wenn auch, glaube ich nicht wirklich besser xD ... wenn ich einen Knoten lösche, will ich auch alle untergeordneten Knoten löschen, damit ich nicht mit new Knoten angelegt habe die ich nicht wieder lösche und mein Speicher überfluten
manni66 schrieb:
Wie kommst du auf die Idee delete this im Destruktor aufzurufen?
ich habe delete this zu delete *it zu machen, in der child schleife ... irgendwie alles komischer gemacht hat ...
vielleicht wehret ihr so nett und könntet mir dabei auch noch helfen ... blicke gerade nicht so ganz durch xD
Hier noch ein mal der etw neuere Code:
Graph.h
#include <iostream> #include <list> template<class T> class Graph { public: T element; std::list<Graph<T>*> childs; std::list<Graph<T>*> parents; Graph(T); ~Graph(); bool makeChild(Graph<T>*); bool deleteChild(Graph<T>*); bool makeParent(Graph<T>*); T getElement(); bool leaf; }; template<class T> Graph<T>::Graph(T element) : element(element) { leaf = true; } template<class T> Graph<T>::~Graph() { if(!leaf) { for (auto it = childs.begin(); it != childs.end();) { // wenn das kind nicht mehrere Väter hat, denen ich es nicht weg nehmen will if ((**it).parents.size()<2) { delete *it ++; } else{ it ++; } } } if (!(*this).parents.empty()) { for (auto it = parents.begin(); it != parents.end(); it++) { //alle Väter vergessen dieses Kind, damit es in ohne folgen beseitigt werden kann (**it).deleteChild(this); } } } template<class T> T Graph<T>::getElement() { return (*this).element; } template<class T> bool Graph<T>::deleteChild(Graph<T>* tokill) { for (auto it = childs.begin(); it != childs.end(); it++) { if( (*it)==tokill){ childs.erase(it); return true; } } // Error code hier einfügen std::cout<<"Leider dieses Kind nicht gefunden. Error main2.h at line 61"<<std::endl; return false; } //eingane der zu setzende Vater. Wenn setzen des Vaters gelingt, wird er in die Liste der Väter aufgenommen template<class T> bool Graph<T>::makeParent (Graph<T>* newParent){ if ((*newParent).makeChild(this)){ parents.push_back(newParent); return true; } else{ //Error code hier einfügen std::cout<<"das Erzeugen dieses Kindes bei dem Vater war nicht möglich. Error main2.h at line 76"<<std::endl; return false; } } template<class T> bool Graph<T>::makeChild(Graph<T>* inTree) { childs.push_back(inTree); (*inTree).parents.push_back(this); leaf = false; return true; }
#include "Graph.h" #include <iostream> #include <string> #include <memory> int main (){ { int count = 0; /* wenn new geht, wird das wieder aktiviert. solange inaktiv std::shared_ptr<Graph<int>> test(new Graph<int>(5)); */ Graph<int>* test = new Graph<int>(5); for (int i = 0; i<2000000;i++){ (*test).makeChild(new Graph<int>(4)); (*test).makeChild(new Graph<int>(2));} for (auto i = (*test).childs.begin(); i != (*test).childs.end() ;i++) { std::cout <<"Das Element " << (*test).getElement() << ":" << count << " ist " << (**i).getElement() << ". Ist es ein Blatt?: " << ((**i).leaf? "yes" : "no") << std::endl; count ++; } count = 0; delete test; } }
Ich habe jetzt folgendes Problem ...
Ich glaube ich lösche meinem Baum nicht vollständig ...
Wenn ich einen Großen Tree erzeuge und ihn dann lösche, ist der Speicher im RAM aber immer noch belegt ... wenn ich diesen Baum aber noch ein mal erzeuge, wird der Belegte speicher nicht größer
(z.b. while(true) schleife um alles, und die Zeile8-9 eine for 2 000 000 schleife)wie mache ich das richtig?
also was habe ich da falsch gemacht?
oder habe ich delete falsch verstanden?danke für eure Hilfe schon ein mal
Grüße
EvDEDIT: Leiche veränderungen im Code (ich hoffe das geht klar wenn ich die hier editiere und nicht immer wieder einen neuen Post auf mache) :
-> umbenennung in Graph
-> ein Kind fügt seinen Vater jetzt in die Parent liste ein (hups xD)
-> Die Kinder werden alle aus der list child des Vaters gelöscht ... aber immer noch nicht aus dem Speicher
-
aber verstehe ich leider immer noch nicht was an meinem falsch war ...
Eigentlich sagt die erste Fehlermeldung alles was es zu sagen gibt. Du musst dort typname benutzen.
Ein Tree mit mehreren „Vätern“ finde ich seltsam. delete wirst du sicher nicht nur für ein Blatt aufrufen wollen.
Benutze einen Debugger!
-
manni66 schrieb:
Ein Tree mit mehreren „Vätern“ finde ich seltsam
Da hast du wohl recht, ich habe es in "Graph" umgeändert der dann auch noch Gerichtet ist ...
manni66 schrieb:
delete wirst du sicher nicht nur für ein Blatt aufrufen wollen
ich delete ja mit "delete *it" alle Kinder des Knoten.
und mit "delete test" lösche ich ja auch den Knoten.Gedacht ist das ich mit delete knoten_A alles was unterhalb von knoten_A ist und knoten_A an sich lösche ... ich dachte das würde ich hier machen ... dachte ... denke ...
Selbst mit dem Debugger komme ich bei dem delete Problem nicht weiter ...
Weil anscheinend lösche ich mit delete *it original nichts ... was mich ein wenig verwirrt ...Ich rufe schon jedes "Blatt" auf ... weil ich für jeden Kind-Knoten delete aufrufe, und den pointer auf den Grapen<T> gebe, der gelöscht werden soll ... alles ein wenig komisch
Ich glaube das ich ein wenig verwirrt bin sieht man daran wie ich Texte schreibe
Soll ich dafür ein neues Thema auf machen, oder kann man das noch hier drinnen beantworten?
Grüße
EvD
-
Wie ich gerade gesagt bekommen habe, soll ich nicht auf die RAM auslastung schauen, weil diese nicht aussagekräftig ist, sondern mit valgrind alles überprüfen ... und das hat mir dann gesagt das alles gut ist
Daher (und deswegen dieser Doppel post) hat sich dieses Thema erledigt
-> Gelöst <-