Bin ich verrückt, ein kleines Garbage-Collection-System in meinen Funktionen neu zu erstellen?

8

Ich habe einige (C ++) Funktionen, die jeweils mehrere Aufrufe enthalten, die ähnliche Arrays des gleichen Basistyps auf dem Heap erzeugen. An verschiedenen Stellen in diesen Funktionen muss ich möglicherweise eine Ausnahme auslösen. Den Überblick darüber zu behalten, welche Arrays gelöscht wurden, ist mühsam und recht fehleranfällig. Daher habe ich darüber nachgedacht, die Array-Zeiger zu einem Set<ArrType*> hinzuzufügen, von dem ich einfach jedes Element löschen kann, wenn ich eine Ausnahme erhalte:

%Vor%

Es fühlt sich ein wenig an wie das Hinzufügen von Epizyklen, aber ich kann nicht umhin zu wissen, dass einer von mehreren externen Anrufen eine Ausnahme auslösen kann, und ich muss definitiv alle Zeiger löschen, die bis zu diesem Punkt zugewiesen wurden.

>

Ist das nur Torheit? Sollte ich nur kleinere Try-Catch-Blöcke um die externen Anrufe hinzufügen? Ich würde immer noch mit kleinen Listen von löschen A enden; B löschen; lösche D; nach jedem ...

    
Phil H 30.07.2009, 15:41
quelle

5 Antworten

2

Sie müssen sich nicht auf die Garbage Collection verlassen.

Sie haben std :: auto_ptr, das eine zeigerähnliche Syntax bietet und ein dynamisch zugewiesenes Objekt umschließt. Wenn es zerstört wird, zerstört es automatisch das Objekt, auf das es zeigt.

Sie könnten etwas ähnliches für Arrays implementieren.

    
Cătălin Pitiș 30.07.2009, 15:44
quelle
19

Warum verwenden Sie keinen intelligenten Zeiger wie boost::shared_array oder verwenden Sie a stack-allokiert std::vector ? Für einzelne Zuweisungen anstelle von Array-Zuweisungen können Sie boost::shared_ptr .

Diese implementieren die RAII für Sie. Selbst wenn Sie ein Konzept wie RAII wiederverwenden, erfinden Sie das Rad immer noch neu, wenn es bereits eine konkrete Implementierung gibt, die Ihren Anforderungen entspricht.

    
Nick Meyer 30.07.2009 15:43
quelle
10

Sie sollten eine RAII-Technik verwenden. Sie delegieren die Zerstörung an ein anderes Objekt, das Sie auf dem Stapel erstellen.

Wenn das Objekt den Gültigkeitsbereich verlässt, wird es alles freigeben, auch wenn es außerhalb des Gültigkeitsbereichs liegt, selbst wenn es eine Ausnahme gibt.

    
Arkaitz Jimenez 30.07.2009 15:42
quelle
8

Anstelle von

%Vor%

Sie brauchen nur:

%Vor%

ohne Fangblock. Alle Zuweisungen und Freigabe (ob Ausnahmen ausgelöst werden oder nicht) werden für Sie behandelt - das ist RAII.

    
anon 30.07.2009 15:58
quelle
2

Sieht so aus, als ob Sie es überdenken.

Verwenden Sie statt {} catch {} den Befehl RAII Es gibt mehrere Möglichkeiten, dies durch die Kommentare zu tun (alle scheinen gültig).

Option 1:
Wenn Sie nur einen einzelnen festen (oder erweiternden Satz von ArrType) benötigen.
Wo die Lebensdauer am Ende der Funktion endet

%Vor%

Option 2:
Wenn Sie mehrere Arrays von ArrType benötigen Wo die Lebensdauer am Ende der Funktion endet

%Vor%

Damit können Sie auch das Array aus dem ptr_vector entfernen, wenn das Objekt eine längere Lebensdauer hat.

Hinweise zu try {} catch {}

  • Fang nach ref
    • Wenn Sie nach einem bestimmten Typ suchen, sind Sie anfällig für das Problem mit dem Aufteilen, da abgeleitete Typen in die im Fangausdruck definierte Variable kopiert werden.
  • Bevorzugen Sie const ref
  • Beim erneuten Werfen Gebrauch werfen; (ohne den Ausdruck)
    • Dies wird die ursprüngliche Ausnahme erneut auslösen, anstatt die neue Ausnahme an die Stelle zu kopieren, an der der Ausnahmebehandlungsmechanismus die Ausnahme während des Abwickelns des Stapels verbirgt.
Martin York 30.07.2009 17:19
quelle

Tags und Links