Hilfe, ob ich dynamische Structuren richtig verstanden habe
-
Hallo zusammen,
ich hab seit Jahren nicht mehr in C++ programmiert. Nun möcht ich wieder Voll Einsteigen. Dazu hab ich ein Programm in C++ geschrieben, welches dynamische Structuren verwendet. Und ich möchte von euch wissen, ob sich Fehler eingeschlichen haben, oder ob es sich vereinfachen läßt.
Programmablauf:
Erstellen eines Structs mit einem Zeiger auf den Typ Struct selber.
Speicher bereitstellen.
Struct mit Zahlen füllen und neue Structs anhängen.
Kompletten Struct löschen.Danke für eure Antworten. MFG.
#include was man so braucht //Definieren des Structs strdrei struct strdrei { int x1; int x2; int x3; strdrei *pweiter; } int main(){ ////////////Struct erstellen strdrei drei; //Struct drei erstellen strdrei *pdrei; //Zeiger pdrei des Typs Struct drei erstellen //Speicher für den Zeiger pdrei bereitstellen try { *pdrei = new strdrei; } catch (bad_alloc &ba) { cout << "Exception abgefangen\n"; cout << ba.what() << endl; exit(1); } *pdrei = &drei; //Adresse von drei dem Zeiger pdrei übergeben pdrei->pweiter=NULL; //Zeiger pweiter auf NULL setzten strdrei *pdreianfang; //Zeiger pdreianfang des Typs Struct drei erstellen //Speicher für den zeiger pdreianfang bereitstellen try { *pdreianfang = new strdrei; } catch (bad_alloc &ba) { cout << "Exception abgefangen\n"; cout << ba.what() << endl; exit(1); } *pdreianfang = &drei; //Adresse von drei dem Zeiger pdreianfang übergeben ///////Daten in Struct eingeben for(int i=0;i<=10;i++) //Schleife von 0 bis 10 { pdrei->x1=i; //Werte in das Struct von drei schreiben pdrei->x2=i*i; pdrei->x3=i+i*2; //Speicher für Zeiger pweiter in Struct drei bereitstellen try { *pdrei->pweiter = new strdrei; } catch (bad_alloc &ba) { cout << "Exception abgefangen\n"; cout << ba.what() << endl; exit(1); } pdrei=pdrei->pweiter; //Zeiger pdrei auf Zeiger pdrei->pweiter setzen pdrei->pweiter=NULL; //Zeiger von pweiter im neuen pdrei auf NULL setzen } ///////Speicher freigeben pdrei=pdreianfang; //Den Zeiger pdrei auf den Anfang des Structs drei setzen for(;pdrei;) //Endlosschleife, bis pdrei==NULL { for(;pdrei->pweiter;) //Im Struct soweit nachhinten gehen, bis pweiter==NULL pdrei=pdrei->pweiter; //Im Struct einen Schritt nach hinten gehen delete(pdrei); //Struct an der Adresse pdrei löschen pdrei=pdreianfang; //Den Zeiger pdrei auf den Anfang des Structs drei setzen } delete(pdreianfang); }
-
Das Programm kann nichtmal compilieren (*pdreianfang = &drei), wie soll es also dann richtig sein?
Wieso machst du zuerst new und überschreibst den Pointer dann mit &drei?
-
Der Quellcode war früher sowas wie
int *pzeiger = &zeiger;
Ich hab später den Code auf zwei Zeilen zerpflückt und vergessen bei pzeiger das * wegzumachen.
Muss ich einem neuen Pointer keinen Speicher reservieren der so groß ist wie die Variable derren Adresse ich ihm übergebe?
-
madking75 schrieb:
Muss ich einem neuen Pointer keinen Speicher reservieren der so groß ist wie die Variable derren Adresse ich ihm übergebe?
Dein Zeiger kann nur auf eines zeigen, entweder auf den reservierten Speicher oder auf die Adresse, die du ihm zuweist. Machst du beides, geht eines von beiden verloren.
int a = 5; a = 3;
Jetzt ist die fünf weg.
pdrei = new strdrei; pdrei = &drei;
Jetzt ist die Adresse des mit new geholten Speichers weg.
-
Okay, ich denke ich habs soweit verstanden. Ist jetzt folgender Code richtig um Sturcts an einem Struct anzuhängen? Ist die Speicherfreigabe correct?
//+Sturct anhängen+ //Definieren des Structs strdrei struct strdrei { int x1; int x2; int x3; strdrei *pweiter; } main() { strdrei drei; //Struct drei erstellen strdrei *pdrei; //Zeiger pdrei des Typs Struct drei erstellen strdrei *pdreianfang; pdrei = &drei; //Adresse von drei dem Zeiger pdrei übergeben pdrei->pweiter=NULL; //Zeiger pweiter auf NULL setzten pdreianfang = &drei; //neuen struct anhängen try { *pdrei->pweiter = new strdrei; } catch (bad_alloc &ba) { cout << "Exception abgefangen\n"; cout << ba.what() << endl; exit(1); } pdrei=pdrei->pweiter; //Zeiger pdrei auf Zeiger pdrei->pweiter setzen pdrei->pweiter=NULL; //Zeiger von pweiter im neuen pdrei auf NULL setzen //Speicher freigeben pdrei=pdreianfang; //Den Zeiger pdrei auf den Anfang des Structs drei setzen for(;pdrei;) //Endlosschleife, bis pdrei==NULL { for(;pdrei->pweiter;) //Im Struct soweit nachhinten gehen, bis pweiter==NULL pdrei=pdrei->pweiter; //Im Struct einen Schritt nach hinten gehen delete(pdrei); //Struct an der Adresse pdrei löschen pdrei=pdreianfang; //Den Zeiger pdrei auf den Anfang des Structs drei setzen } delete(pdreianfang); }
-
Bevor einer fragt warum ich es nicht selbst teste: Ich habe im Moment noch keinen Compiler, Linux läuft noch nicht richtig. Zudem kann man ja Speicherlecks nur dann sehen, wenn der Speicher immer weniger wird.
-
madking75 schrieb:
Ist jetzt folgender Code richtig um Sturcts an einem Struct anzuhängen?
Keine Ahnung, irgendwie sieht das alles etwas konfus aus. Aber hier mal ein paar Tipps
- main() fehlt der Rückgabetyp (int) - eine return Anweisung ist nicht erforderlich, mach sie aber trotzdem hin
- es gibt noch andere Schleife als for
- die Klammerung bei delete ist überflüssig, zB reichtdelete pdrei;
vollkomen aus
- auf pdreianfang darfst du delete nicht anwenden, da pdreianfang auf eine Variable im Stack zeigt
-
Und wenn du dann noch das pweiter auf NULL setzt, nachdem es gelöscht ist, dürfte es ja schon funktionieren. Nur ist es nicht gerade wünschenswert, beim Freigeben einer Liste quadratischen Zeitaufwand zu haben.
-
Wie groovemaster schon gepostet hat: sieht alles sehr wirr aus. Ich erlaube mir mal ne einfache Lösung zu präsentieren
struct strdrei { int x1; int x2; int x3; strdrei *pweiter; } int main() { strdrei *pdrei = NULL; strdrei *tmp; // wir erzeugen jetzt mal 10 Objekte vom Typ strdrei und ketten sie aneinander for (int i=0 ; i<10 ; i++) { // wir erzeugen ein neues Objekt tmp = new strdrei; // wir hängen die vorher erzeugte Liste an den neuen Eintrag tmp->pweiter = pdrei; // Der neue Eintrag ist jetzt der erste in unserer Liste pdrei = tmp; } // und löschen das Ganze wieder while(pdrei) { tmp = pdrei; // erster Eintrag in der Liste merken pdrei = pdrei->pweiter; // einen Eintrag in der Liste weiterspringen delete tmp; // gemerkten Eintrag löschen } return 0; }
-
Danke, dass ist ja natürlich viel Einfacher. Bin gar nicht auf den Gedanken gekommen die Liste von hinten nach vorne zu machen. Super damit geht es.
Super Forum hier. Tschüß.