Kann mir jemand eben erklären, wie die Kopierkonstruktoren mit Referenzparameter funktionieren?
-
@manni66 Eben.^^
Das hab ich mich halt auch gefragt^^
-
Dieser Beitrag wurde gelöscht!
-
int* int_pointer; *int_pointer = *other_int_pointer;
Und wohin wird da jetzt kopiert?
funktioniert = stürzt nicht sofort ab, sondern erst später
-
...und außerdem war im Original
char *data =new char[27]
. Also 27 chars. Und die 27 war einfach mal so gewählt. Was, wenn du in einer Instanz 27 und in der anderen 13476 Chars hast? Das geht so nicht, du müsstest neuen Speicher reservieren usw. Und woher soll der Compiler bei*data = *other.data
irgendwas über Längen wissen?!
-
@titan99_ sagte in Kann mir jemand eben erklären, wie die Kopierkonstruktoren mit Referenzparameter funktionieren?:
Ob es sinnvoll ist und ob Türen für andere Fehler geöffnet werden, ist eine andere, Frage finde ich.
Es wäre dazu gedacht gewesen, um den Unterschied zu zeigen, wenn man Adressen in Pointern kopiert oder Adressen in Pointer dereferenziert und so die Werte kopiert, was ja auch dem Namen Copy entspricht.
So sollte es etwas besser sein.
int int_variable; int* int_pointer = &int_variable; ^ Address-of operator *int_pointer = *other_int_pointer; ^ ^ Dereference operator
-
-
@JTR666 sagte in Kann mir jemand eben erklären, wie die Kopierkonstruktoren mit Referenzparameter funktionieren?:
@SeppJ Also nochmal bei 0 anfangen?
Na, bevor du weiter Quatsch lernst. Je mehr Quatsch du lernst, desto schwieriger wird es, diesen zu vergessen. Besonders weit bist du ja noch nicht, insofern ist jetzt ja noch ein guter Zeitpunkt zu wechseln.
Falls du das anders siehst, stell' dir mal vor, du würdest ein Instrument oder einen Sport anhand von Internetvideos lernen und gingest jetzt zu einem professionellen Lehrer/Trainer. Und der sagt dir, dass du dir eine falsche Haltung angewöhnt hast, weil dich bisher niemand korrigiert hat. Würdest du darauf bestehen, so weiter zu machen, wie bisher? Wohl hoffentlich nicht, auch dann nicht, wenn dir die neue Haltung vom Trainer zuerst schwer fällt, und du damit anfangs Sachen nicht schaffst, die du mit deiner falschen Haltung schon konntest.
-
@JTR666 sagte in Kann mir jemand eben erklären, wie die Kopierkonstruktoren mit Referenzparameter funktionieren?:
@Quiche-Lorraine Was hat er gemacht?
Er hat eine Speicherverwaltung für einen Uralt-Controller geschrieben. Dazu hat er einen Großteil des RAMs (32 kByte) für sich beansprucht und eigene HeapNew() und HeapDelete() Funktionen geschrieben. Und da er die Speicherverwaltung sich selbst organisierend machte um Fragmentierung zu vermeiden, lieferten HeapNew() und HeapDelete() nur IDs zurück. Eine Funktion HeapPtr() lieferte zu einer ID den Pointer zurück.
Und dann wollte eine Funktion beispielsweise eine Liste kopieren und machte folgendes:
// Bestimmte Pointer auf zu kopierendes Array tMyArray* Array = HeapPtr(ArrayID); // Lege neues Array an int NewArrayID = HeapNew(sizeof(tMyArray)); tMyArray* NewArray = HeapPtr(NewArrayID); // Kopiere Elemente for (i = 0; i < Array->Count; i++) { NewID = HeapNew(4); memcpy(GetPtr(NewID), GetPtr(Array->Data[i]), 4); NewArray->Data[i] = NewID; NewArary->Count++; }
Den Fehler sieht man auf den ersten Blick nicht. Aber das HeapNew() organisierte manchmal den Speicher um s.d. alle Zeiger auf dem Speicherbereich ungültig wurden und auf potenziell ungültige Daten zeigten.
Und das dumme daran, es stürzte noch nicht einmal ab. Der Zeiger konnte nach einer HeapNew() auf einmal auf einen Speicherbereich zeigen welcher von anderen Funktionen benutzt wurden. Und dann kopierte die Funktion halt Daten nach irgentwo.
Das ganze funktionierte in 99% der Fälle aber in 1% der Fälle verursachte es schwer nachvollziehbare Datenverluste.
Und dann portierte er das ganze auf Windows.
Als ich die Speicherreservierung auf std::vector umstellte, stürzte mir das Programm erst einmal ab. Und das war auch gut so. Denn nur so fand ich den Fehler.
PS:
Aber auch so etwas habe ich schon gesehen:#include <stdio.h> #include <vector> int main () { std::vector<int> L{1}; int* L1 = &L[0]; for (int i = 0; i < 20; i++) { printf("%i ", *L1); L.push_back(i); } return 0;
}
-
@JTR666
Die Lehre aus dieser Geschichte: Pointer sind kleine gemeine Biester, welche einem das Programmierleben orgentlich versauen können. Aber machmal sind sie auch sehr hilfreiche Wesen.
-
@SeppJ Also kennst du das für Dummies-Buch, oder wie?
-
@Quiche-Lorraine Eine grammatikalische Frage:
Meinst du in der ersten Kommentar-Zeile mit "Bestimmte", dass deine Bekannter die Zeiger bestimmte, oder dass es sich um bestimmte, also spezielle, Zeiger handelt?
-
@Quiche-Lorraine Also beim zweiten Quellcode (dem ich zugegebenermaßen besser weit besser folgen kann als dem ersten), kommt es mir so vor, als versuche er/sie immer wieder einen Vektor mit nur einem Wert (warum dann überhaupt einen Vektor aufspannen?) zu überschreiben.
Und beim ersten meinst du dann sicherlich, dass sich das Programm einfach Speicher nimmt, der schon von externen Programmen belegt (aber wohl nicht ordentlich reserviert) war, und diesen dann einfach überschreibt, richtig?
-
@SeppJ Btw:
Das Buch ist das was ich meinte, dass ich von Stroustrup hab:
https://books.google.de/books/about/Die_C++_Programmiersprache.html?id=YEy9BgAAQBAJ&printsec=frontcover&source=kp_read_button&redir_esc=y#v=onepage&q&f=false
-
@JTR666 sagte in Kann mir jemand eben erklären, wie die Kopierkonstruktoren mit Referenzparameter funktionieren?:
@Quiche-Lorraine Also beim zweiten Quellcode (dem ich zugegebenermaßen besser weit besser folgen kann als dem ersten), kommt es mir so vor, als versuche er/sie immer wieder einen Vektor mit nur einem Wert (warum dann überhaupt einen Vektor aufspannen?) zu überschreiben.
Mag sein, dass es dir so vorkommt, ist aber nicht so. Schau genauer hin.
Und beim ersten meinst du dann sicherlich, dass sich das Programm einfach Speicher nimmt, der schon von externen Programmen belegt (aber wohl nicht ordentlich reserviert) war, und diesen dann einfach überschreibt, richtig?
Nein. Du kannst bei modernen Betriebssystemen nicht einfach so in Speicher anderer Programme schreiben. Das
Array
aus Zeile 2 darf nach demHeapNew
-Aufruf in Zeile 4 schlicht nicht mehr verwendet werden.
-
@Quiche-Lorraine Dann vermute ich mal, dass der Pointer, der ja auf das erste (und einzige) Element des Vektors zeigt, immer an die Adresse auf die er zeigt ein neues Element schiebt, und dadurch die vorherigen Elemente irgendwo hingeschoben, aber nicht gelöscht werden?
-
@JTR666 sagte in Kann mir jemand eben erklären, wie die Kopierkonstruktoren mit Referenzparameter funktionieren?:
@Quiche-Lorraine Dann vermute ich mal, dass der Pointer, der ja auf das erste (und einzige) Element des Vektors zeigt, immer an die Adresse auf die er zeigt ein neues Element schiebt, und dadurch die vorherigen Elemente irgendwo hingeschoben, aber nicht gelöscht werden?
Wie kommst du auf deine Vermutung? Schau dir das doch mal Zeile für Zeile an. Wie soll ein Pointer irgendwas schieben?
-
@Schlangenmensch Nicht der Pointer. Sondern push_back schiebt ja.
Denn ich denke mal, dass die Vektorgröße nicht dynamisch ist und somit immer nur aus einem Element besteht.
-
@JTR666 sagte in Kann mir jemand eben erklären, wie die Kopierkonstruktoren mit Referenzparameter funktionieren?:
Denn ich denke mal, dass die Vektorgröße nicht dynamisch ist und somit immer nur aus einem Element besteht.
Und was bringt dich auf die Idee? Um das zu verkürzen: Das ist falsch. Genau das ist die Anwendung von std::vector: als dynamisches array.
push_back()
fügt ein Element ans Ende ein und vergößert es damit.
-
Dieser Beitrag wurde gelöscht!
-
@JTR666 Probier es doch mal aus. Das ist auch nicht das Problem.
%i
ist nur ein format specifier, damit printf weiß, was es auszugeben hat.Edit: Arbeite mal das Buch von Bjarne Stroustrup durch