Frage

Ich diskutierte mit einigen Kollegen über das, was passiert, wenn Sie eine Ausnahme in einer dynamisch zugewiesenen Klasse werfen. Ich weiß, dass malloc wird aufgerufen, und dann den Konstruktor der Klasse. Der Konstruktor nie zurückgibt, so was passiert mit der malloc?

Betrachten Sie das folgende Beispiel:

class B
{
public:
    B()
    {
        cout << "B::B()" << endl;
        throw "B::exception";
    }

    ~B()
    {
        cout << "B::~B()" << endl;          
    }
};

void main()
{
    B *o = 0;
    try
    {
        o = new B;
    }
    catch(const char *)
    {
        cout << "ouch!" << endl;
    }
}

Was ist mit dem malloced Speicher o geschieht, ist es undicht? Hat die CRT die Ausnahme des Konstrukteurs fangen und den Speicher freigeben?

Cheers!
Rich

War es hilfreich?

Lösung

Ein Aufruf

new B();

löst in zwei Dingen:

  • Zuweisung mit einem Operator new () (entweder global oder eine Klasse spezifische, möglicherweise eine Platzierung einer mit der Syntax new (xxx) B())
  • den Konstruktor aufrufen.

Wenn der Konstruktor werfen, löschen Sie den entsprechenden Operator aufgerufen wird. Der Fall, in dem der entsprechenden Lösch ist eine Platzierung ist der einzige Fall, in dem eine Platzierung löscht Operator ohne die Syntax aufgerufen :: operator delete (). delete x; oder delete[] x; Sie die Platzierung Betreiber löschen nicht anrufen und es gibt keine ähnliche Syntax Platzierung neu, sie zu nennen.

Beachten Sie, dass während der Destruktor von B wird nicht bezeichnet werden, bereits errichteten Subobjekte (Mitglieder oder B und Basisklassen B) wird zerstört werden, bevor der Anruf an Betreiber löschen. Das Konstruktor, der aufgerufen wird, nicht das Richtige für B.

Andere Tipps

Wenn eine Ausnahme von dem Konstruktor geworfen wird, der Speicher durch neue zugewiesen wird freigegeben, aber der destructor der Klasse B nicht aufgerufen wird.

In diesem Fall Ihr Objekt, o, erhält nicht wirklich gebaut, und der Speicher durch neue zugewiesen wird befreit. Als solches ist der destructor nicht aufgerufen. So brauchen Sie nicht aufrufen:

delete o;

Ein interessantes Design-Muster ist RAII - Ressourcenerfassung ist die Initialisierung. In diesem Muster verwenden Sie einen Konstruktor den Erwerb einer Ressource zu kapseln, und lassen Sie die Ressource in dem destructor. Wenn die Ressource nicht erfasst werden können, werfen Sie im Konstruktor - ähnlich wie Ihr Beispiel. Wenn Sie also ein gültiges Objekt haben, haben Sie die Ressource.

Wenn das Objekt aufgebaut ist, dann haben Sie erworben erfolgreich die Ressource. Dies bedeutet, dass für das Leben des Objekts, die Ressource besitzen. Wenn das Objekt gelöscht wird, wird die Ressource freigegeben. Wenn das Objekt nie aufgebaut ist, dann erlangt man nie auf die Ressource. Siehe Wikipedia:

http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization

Von dem C ++ 2003 Standard 5.3.4 / 17 - Neu:

  

Falls ein Teil der Objekt Initialisierung oben endet beschrieben durch eine Ausnahme und eine geeignete Aufhebung der Zuordnung Funktion wirft gefunden werden kann, die Aufhebung der Zuordnung Funktion aufgerufen, um den Speicher freizugeben, in dem das Objekt konstruiert wird, wonach die Ausnahme propagieren weiterhin im Zusammenhang mit dem neuen Ausdruck. Wenn keine eindeutige passende Deallokation Funktion gefunden werden kann, wird die Ausnahme propagieren nicht dazu führen, den Speicher des Objekts befreit werden. [Anmerkung: Diese geeignet ist, wenn die genannte Zuteilungsfunktion Speicher zuweisen nicht; sonst ist es wahrscheinlich zu einem Speicherverlust führen. ]

So kann es oder auch nicht einen Leck sein - es hängt davon ab, ob ein geeigneter deallocator gefunden werden kann (was normalerweise der Fall ist, es sei denn, Betreiber Neu / Löschen überschrieben wurde) .In den Fall, dass es eine geeignete deallocator, die Compiler ist für die Verdrahtung in einem Aufruf an sie, wenn der Konstruktor wirft.

Beachten Sie, dass diese mehr oder weniger unabhängig von ist, was zu den Ressourcen geschieht im Konstruktor erworben, die etwas zu einer Antwort mein erster Versuch ist diskutiert -. Und ist eine Frage, die in vielen FAQs, Artikel diskutiert wird, und Buchungen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top