Hallo Zusammen
Ich habe eine kleine, vermutlich ziemlich einfach zu lösende Frage bezüglich des "delete" in meinem C++ Code.
Zuerst die Intension... Ich wollte einen Gerichteten Graphen Programmieren, der dann in ein Größeres Projekt einfließen soll. der dort benutzte Datentyp ist Variabel, daher template's
Da ich noch relativ frisch in der C++ Gegend angle, verzeiht mir wenn ich mit dem Code in dem Trüben fische.
Ich habe in den Code verweise eingebaut (/*xyz*/) an denen ich mich bei der Fragestellung Orientiere. Und hier mein Code (Graph.h):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #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) { /*4*/ 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) { /*5*/ delete *it ++; } else{ it ++; } } } if (!(*this).parents.empty()) { /*6*/ 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; } |
Zum testen habe ich dann auch noch eine main geschrieben, die Hier ist (main.cpp):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #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>(12)); */ /*1*/ Graph<int>* test = new Graph<int>(12); /*2*/ for (int i = 0; i<2;i++){ (*test).makeChild(new Graph<int>(9)); (*test).makeChild(new Graph<int>(18));} 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; /*3*/ delete test; } } |
Soweit zu dem...
Nun zu den Vermerken:
1) Erzeugen eines neuen Graphen und einen Pointer auf ihn (test)
2) 4 Knoten erstellen, die alle unter Knoten "19" sind mit new (ansonsten wehren die ja sofort wieder weg)
3) Sollte test Löschen, und damit ~Graph() aufrufen und den Speicher frei geben (Spoiler, das mit dem Speicher macht er nicht)
4) Wenn ein Knoten Gelöscht wird, werden auch alle Kinder gelöscht mit nur einem Vater
5) sollte das Kind löschen und damit vom Kind ~Graph() aufrufen und Speicher frei geben (Spoiler, auch hier das gleiche wie bei 3) )
6) Löscht sich aus der Liste childs von seinen Vätern raus. Nun sollte kein Pointer mehr auf den Speicher zeigen innerhalb des Graphen, bedenkenloses löschen möglich!
Wenn ich das jetzt ausführe wird des Speicher aber nicht gelöscht ... warum denn ... ich verstehe das nicht ...
Wehre unglaublich nett wenn ihr mir dabei helfen könntet ☺
Grüße EvD
Ps.: Mir geht es darum etwas zu lernen. Ich lerne nur wenig wenn ihr mir sagt ich solle das einfach includen, oder ihr ein Programm von euch Postet (da lerne ich wenigstens noch n bisschen was) Bitte einfach einen Tipp geben wo da der Fehler ist ☺