Im Stroustrup Buch ( Die C ++ Programmiersprache 4. Aufl. , §17.5.1, pag 508) fand ich das folgende Beispiel eines Kopierkonstruktors für eine einfache Matrix
Klasse:
( elem
ist der Zeiger auf das Array von T Elementen, deklariert als T* elem;
).
Ich habe zwei Fragen zu diesem Kopierkonstruktor:
Warum erstellt die Methode zuerst ein Array von m.size()
-Elementen, nur um es im Text mit dem uninitialized_copy
-Aufruf zu überschreiben?
mit der Initialisierung elem{ new T[ m.size() ] }
, der Konstruktor von T heißt m.size()
mal. Der Algorithmus uninitialized_copy
im Rumpf ruft jedoch den T-Destruktor nicht auf, bevor er das neue Array im selben Bereich erstellt. Ist dies ein potenzielles Ressourcenleck? (Anmerkung: kein Speicherleck, ein Ressourcenleck, z. B. wenn T eine Sperre oder einen Dateideskriptor im Ctor erwirbt und im dtor freigibt).
Danke
Ja, das ist eindeutig ein Fehler; Der Code sollte copy
anstelle von uninitialized_copy
verwenden. Da T
normalerweise ein trivialer Typ ist, wird das Ressourcenleck normalerweise vermieden, aber es ist immer noch ein Fehler.
Um Ihre erste Frage zu beantworten, ist es einfacher, den Konstruktor-Member-Initialisierer-Standard zu schreiben, der ein Array konstruiert, da der Kopierkonstruktor die gleiche einfache Zuordnungsmethode wie der (n, m)
-Konstruktor verwenden kann. Es wäre effizienter, einen nicht initialisierten Speicherbereich und Konstrukt zuzuweisen, aber das würde die Konstruktoren und Destruktoren komplizierter machen, was den Punkt der Matrix-Klasse beeinträchtigen würde. Die idiomatischere Art, dies zu schreiben, wäre, wenn Matrix eine dynamische Array-Klasse (Vektor mit fester Größe) umschließt, zum Beispiel dynarray
(möglicherweise nach C ++ 14 TS).
Wie Puppy bemerkt hat, hat der Kopierkonstruktor ein Speicherleck, wenn sein Body ausgelöst wird. Dies geschieht unabhängig davon, ob copy
oder uninitialized_copy
verwendet wird. Stroustrup sagt // simplified (no error handling)
früher in der Klasse, also kann dies entschuldigt werden.
Bei einer Schätzung würde ich sagen, dass dieser Fehler darin lag, dass Stroustrup uninitialized_copy
anderswo im Buch verwendet, insbesondere in seiner Vektorklasse. Ich habe keinen Zugriff auf die älteren Editionen, aber ich habe den Verdacht, dass dies hinzugefügt wurde, um eine Schleife und einen Versuch / Fang-Block im Vektorkopiekonstruktor zu ersetzen, und Matrix wurde in ähnlicher Weise ohne vollständige Berücksichtigung modifiziert.
Es wird nicht in Stroustrups Errata-Liste für die 4. Ausgabe angezeigt, aber er ist sich dessen vielleicht bereits bewusst (die Errata-Seite) wurde zuletzt aktualisiert November 2013). Wenn du ihn mit diesem Fehler mailst, solltest du es auf jeden Fall tun!
Ich bin der Autor der Frage.
Ich stellte meine zwei Fragen per E-Mail an Bjarne Stroustrup und wollte seine Antworten hier teilen.
Er freundlicherweise (und kurz :-) antwortete:
Er schrieb auch, dass er den Fehler beheben wird.
Tags und Links c++