Problem mit Exception



  • Ich habe folgendes Problem:

    void f()
    {
       int* x = new int[300];
       int* y = new int[600];
    
       ...
       throw "Fehler";
       ...
    
       /* Wie kann man dafür sorgen dass diese Funktionen auf jeden Fall 
          aufgerufen werden ? */
       delete [] x;
       delete [] y;
    }
    


  • Tja, dazu gibt es zwei Möglichkeiten:

    Entweder Du schreibst das delete brav in einen catch-Block und außerhalb nochmal, falls die Exception weiterfliegen soll. Das ist sehr unschön.
    Oder Du verwendest einen geeigneten smart-pointer. (Für arrays nicht std::auto_ptr, aber bei boost gibt's ein paar feine Sachen)

    Allgemein solltest Du solche Allokationen immer mit einem Objekt auf dem Stack verbinden. Konstruktor allokiert den Speicher, Destruktor gibt ihn wieder frei. Da das Objekt auf dem Stack liegt wird es im Falle einer Exception beim Verlassen der Funktion auf jeden Fall zerstört. Diese Technik nennt sich RAII (Resource Allocation Is Initialization), müßte im Netz einiges dazu zu finden sein. Das ist genau der Trick, den alle smart-pointer verwenden.

    MfG Jester



  • boost::scoped_array wäre hier das passendste. Ich würde einfach std::vector nehmen. IMHO sollte man generell nirgends delete/delete[]/sonstige Freigabefunktionen direkt aufrufen. Man erspart sich unglaublich viel Arbeit und Zeit, wenn man alles von Smart-Ptrn & Co machen lässt.



  • Und wie soll ich es bei Funktionen machen, die ich nicht in eine Klasse packen kann, wie z.B. CreateWindow, DestroyWindow...



  • Warum kannst du die nicht in eine Klasse packen? Hat bei mir immer ganz gut geklappt.

    class Window
    {
    private:
        HWND m_handle;
        Window(const Window&);
        Window& operator=(const Window&);
    
    public:
        Window(HWND handle = 0) : m_handle(handle);
        ~Window() { if (handle) DestroyWindow(handle); }
        operator HWND() const { return m_handle; }
    };
    

    (Oder so)
    Bei wirklich exotischen Sachen, die man nur ein- oder zweimal verwendet, kann man aber wohl ein Auge zudrücken... 😉



  • a=a->next schrieb:

    Und wie soll ich es bei Funktionen machen, die ich nicht in eine Klasse packen kann, wie z.B. CreateWindow, DestroyWindow...

    Nimm Alexandrescus ScopeGuard - http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm



  • std::vector ist der auto pointer für arrays



  • gru schrieb:

    std::vector ist der auto pointer für arrays

    Jein.
    std::vector macht oft mehr als nötig.
    zB kann er mehr speicher allkorieren als nötig



  • Außerdem hat ein std::vector Wertsemantiken, wohingegen std::auto_ptr Verschiebungssemantiken hat, die hauptsächlich für die Wertrückgabe nützlich sind. Das kann zwar wegoptimiert werden (bei der Rückgabe z.B.), aber man muss schon anders damit umgehen.


Anmelden zum Antworten