Probleme mit Pointern und Arrays (und Pointer-Arrays)
-
Schau mal hier.
-
Vicious Falcon schrieb:
Schau mal hier.
Dankeschön.
Aber wenn ich das richtig sehe, gibt es da keine elegantere Möglichkeit, eine ganz bestimmte Permutation zu erreichen, als 20-mal
next_permutationaufzurufen, wenn es sich z.B. um die 20. Permutation handelt, oder?Und da meine Elemente keine Zahlen oder Buchstaben sind und damit kein
operator<definiert ist, müsste ich auch den Größenvergleich zweier Elemente erst noch programmieren, oder?
-
Gibt es denn keine Möglichkeit, z.B. die Zeilen 25, 27 und 30 im Code im allerersten Beitrag so zu ändern, dass nur die Pointer umsortiert werden und die Inhalte unberührt bleiben?
(Ich dachte vielleicht an sowas wie
ELEMENT (*temp)[anzahl];in Zeile 25, aber dazu kenne ich mich eben noch zu wenig mit Pointern aus.)Oder ist so etwas gar nicht möglich, wenn
elementeein Array vonELEMENTist und beim Anlegen des Arrays die Reihenfolge der Plätze im Speicher bereits für seine ganze Lebenszeit festgelegt ist?So etwa wird
elementeübrigens erzeugt:MENGE::MENGE(short anzahl) { elemente = new ELEMENT[anzahl]; //... }Vielen Dank für weitere Tipps!
-
tda schrieb:
Ich habe
newverwendet, weil die damit erzeugten Objekte- unter Umständen recht groß werden können (z.B. um die 3800 long integer enthalten) und
Na und? Das machen die Standardcontainer doch sowieso? - nicht wie hier in
main(), sondern in anderen Funktionen (oder Konstruktoren) erzeugt werden und dann ja nicht am Ende der Funktion zerstört werden sollen.
Ungewöhnliche Objektlebensdauer ist tatsächlich einer der wenigen Fälle, wo new gerechtfertigt ist. Wobei es mich doch stark wundert, dass ausgerechnet du zu den wenigen Leuten gehörst, die solch eine spezielle Lebensdauer tatsächlich brauchen.
SeppJ schrieb:
Und über die Verwendung von short brauche ich auch nichts zu sagen, oder?
Äh?
Doch, bitte!Du tauscht hier Platz (der vom Compiler wahrscheinlich ohnehin wieder hochgepadded wird) gegen Geschwindigkeit.
- unter Umständen recht groß werden können (z.B. um die 3800 long integer enthalten) und
-
tda schrieb:
Gibt es denn keine Möglichkeit, z.B. die Zeilen 25, 27 und 30 im Code im allerersten Beitrag so zu ändern, dass nur die Pointer umsortiert werden und die Inhalte unberührt bleiben?
(Ich dachte vielleicht an sowas wie
ELEMENT (*temp)[anzahl];in Zeile 25, aber dazu kenne ich mich eben noch zu wenig mit Pointern aus.)Oder ist so etwas gar nicht möglich, wenn
elementeein Array vonELEMENTist und beim Anlegen des Arrays die Reihenfolge der Plätze im Speicher bereits für seine ganze Lebenszeit festgelegt ist?Das ist nicht möglich, da du da kein Array von Pointern, sondern ein Array von konkreten Objekten hast.
-
Danke für die Antworten. Ich habe mir das alles nochmal genauer angeschaut und kann meine Frage jetzt vielleicht ein bisschen konkreter formulieren:
SeppJ schrieb:
Das ist nicht möglich, da du da kein Array von Pointern, sondern ein Array von konkreten Objekten hast.
Das verstehe ich soweit. Nun kommt aber begünstigend hinzu, dass jedes
ELEMENTselbst wiederum nur aus Zeigern auf Objekte einer weiteren Klasse (und einembool) besteht*:class ELEMENT { private: TEIL *a_teil; TEIL *b_teil; bool info; //... };Sollte es da nicht möglich sein, eine Kopie von einem
ELEMENT(also von den Adressen vona_teilundb_teil, nicht den Inhalten) intempzu speichern (siehe wieder Zeilen 27 und 30 im ersten Beitrag) und dann - neu geordnet - wieder in die jeweiligenELEMENTe zurück zu kopieren?
Ganz am Rande: Da sich die Größe der TEIL-Objekte (die selbst wieder Arrays enthalten) erst während der Laufzeit ergibt, konnte ich nur Pointer benutzen und kann den Speicherplatz derTEILe erst im Konstruktor vonELEMENTanfordern, was vielleicht die Frage nach meinem exzessiven Gebrauch vonnewbeantwortet.
-
tda schrieb:
SeppJ schrieb:
Das ist nicht möglich, da du da kein Array von Pointern, sondern ein Array von konkreten Objekten hast.
Das verstehe ich soweit. Nun kommt aber begünstigend hinzu, dass jedes
ELEMENTselbst wiederum nur aus Zeigern auf Objekte einer weiteren Klasse (und einembool) besteht*:class ELEMENT { private: TEIL *a_teil; TEIL *b_teil; bool info; //... };Sollte es da nicht möglich sein, eine Kopie von einem
ELEMENT(also von den Adressen vona_teilundb_teil, nicht den Inhalten) intempzu speichern (siehe wieder Zeilen 27 und 30 im ersten Beitrag) und dann - neu geordnet - wieder in die jeweiligenELEMENTe zurück zu kopieren?Sofern du keine Deep Copy machst, passiert dass doch sowieso schon. Da du eine Deep Copy explizit programmieren müsstest, ist dies bei dir vermutlich der Fall. Falls du dein Objekt schon so programmiert hast, dass eine Tiefkopie erzeugt wird, dann füg ihm eben eine entsprechende Methode zu, um diese zu vermeiden.
Ganz am Rande: Da sich die Größe der TEIL-Objekte (die selbst wieder Arrays enthalten) erst während der Laufzeit ergibt, konnte ich nur Pointer benutzen und kann den Speicherplatz derTEILe erst im Konstruktor vonELEMENTanfordern, was vielleicht die Frage nach meinem exzessiven Gebrauch vonnewbeantwortet.Das sind alles keine Gründe für new.
-
SeppJ schrieb:
tda schrieb:
Sollte es da nicht möglich sein, eine Kopie von einem
ELEMENT(also von den Adressen vona_teilundb_teil, nicht den Inhalten) intempzu speichern (siehe wieder Zeilen 27 und 30 im ersten Beitrag) und dann - neu geordnet - wieder in die jeweiligenELEMENTe zurück zu kopieren?Sofern du keine Deep Copy machst, passiert dass doch sowieso schon.
Ich weiß zwar nicht genau, was Deep Copy ist, aber ich vermute mal, dass ich alle Membervariablen quasi „zu Fuß“ einzeln kopiere. Solch eine Funktion
ELEMENT::kopieren_von(const ELEMENT &vorlage)habe ich in der Tat auch, aber die benutze ich an dieser Stelle nicht, da ich das Hin- und Herkopieren der Inhalte ja gerade vermeiden will.Das Kopieren von
elemente[j]nachtemp[j]und zurück funktioniert auch (wenn ich mir z.B. mal die Speicheradressen derTEILe jeweils ausgeben lasse), aber nach Ende der Funktionpermutierengibt es einenSegmentation fault, wenn ich danach erneut aufelemente[j]zugreifen will.Ich vermute ja, dass beim Löschen von
tempja der entsprechende Speicherbereich gelöscht wird - der ja jetzt aber auch gleichzeitig Speicherbereich vonelementeist. Kann das die Ursache sein?Und kann ich das vielleicht verhindern, indem ich irgendwas mit
&tempoder*tempstatttempmache oder so? Oder irgendwie anders? Vielen Dank im Voraus?
-
tda schrieb:
Ich weiß zwar nicht genau, was Deep Copy ist,
Den Fachbegriff habe ich natürlich genannt, damit du ihn einfach ignorierst
.aber ich vermute mal, dass ich alle Membervariablen quasi „zu Fuß“ einzeln kopiere.
Nein.
Solch eine Funktion
ELEMENT::kopieren_von(const ELEMENT &vorlage)habe ich in der Tat auch, aber die benutze ich an dieser Stelle nicht, da ich das Hin- und Herkopieren der Inhalte ja gerade vermeiden will.Also doch der Inhalte? Dann ja. Was denn nun? Und ist das ein Extra-Member oder dein Kopierkonstruktor/Zuweisungsoperator?
Das Kopieren von
elemente[j]nachtemp[j]und zurück funktioniert auch (wenn ich mir z.B. mal die Speicheradressen derTEILe jeweils ausgeben lasse), aber nach Ende der Funktionpermutierengibt es einenSegmentation fault, wenn ich danach erneut aufelemente[j]zugreifen will.
Was ist denn jetzt ein TEIL?Ich vermute ja, dass beim Löschen von
tempja der entsprechende Speicherbereich gelöscht wird - der ja jetzt aber auch gleichzeitig Speicherbereich vonelementeist. Kann das die Ursache sein?So funktioniert das mit dem Kopieren und dem Löschen nicht
Und kann ich das vielleicht verhindern, indem ich irgendwas mit
&tempoder*tempstatttempmache oder so? Oder irgendwie anders?Wenn man nur rät was richtig sein könnte, funktioniert das nicht mit dem Programmieren. Du musst von jedem einzelnen Zeichen in deinem Programm genau wissen, was es macht und wozu.
-
SeppJ schrieb:
Und ist das ein Extra-Member oder dein Kopierkonstruktor/Zuweisungsoperator?
Ein Member. Den Zuweisungsoperator habe ich für meine Objekte nicht extra definiert.
Was ist denn jetzt ein
TEIL?Siehe diesen vorigen Beitrag.
Ich vermute ja, dass beim Löschen von
tempja der entsprechende Speicherbereich gelöscht wird - der ja jetzt aber auch gleichzeitig Speicherbereich vonelementeist. Kann das die Ursache sein?So funktioniert das mit dem Kopieren und dem Löschen nicht
Hm, warum kann ich dann aber, nachdem
tempgelöscht wurde, nicht mehr aufelementezugreifen?Und kann ich das vielleicht verhindern, indem ich irgendwas mit
&tempoder*tempstatttempmache oder so? Oder irgendwie anders?Wenn man nur rät was richtig sein könnte, funktioniert das nicht mit dem Programmieren. Du musst von jedem einzelnen Zeichen in deinem Programm genau wissen, was es macht und wozu.
Ja, sehe ich ja genauso. Deswegen frage ich ja hier in die Runde, bevor ich drauflos rate: lässt sich aus diesem Gedanken etwas Sinnvolles machen?
Vielen Dank im Voraus für Tipps!