Ressourcenleck in Stroustrup Beispiel mit std :: uninitialized_copy?

8

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:

%Vor%

( elem ist der Zeiger auf das Array von T Elementen, deklariert als T* elem; ).

Ich habe zwei Fragen zu diesem Kopierkonstruktor:

  1. Warum erstellt die Methode zuerst ein Array von m.size() -Elementen, nur um es im Text mit dem uninitialized_copy -Aufruf zu überschreiben?

  2. 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

    
Daniele Pallastrelli 21.07.2014, 07:56
quelle

2 Antworten

3

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!

    
ecatmur 21.07.2014, 08:54
quelle
5

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:

  1. Es ist ein Versehen und eine Verschwendung.
  2. Ja, wenn ein Typ T Ressourcen enthält, ist es ein Leck

Er schrieb auch, dass er den Fehler beheben wird.

    
Daniele Pallastrelli 21.07.2014 16:10
quelle

Tags und Links