Matrix Template: Wieso wird Destruktor zweimal aufgerufen???



  • Hallo,

    ich will eine kleine Matrix-Klasse schreiben.
    Die sieht bisher ungefähr so aus (noch recht rudimentär):

    template <class T>
    class CMatrix
    {
    private:
    	T** fmatrix;	
    	const int fzeilen;
    	const int fspalten;
    
    public:
    	//Konstruktoren
    	CMatrix()
    	{
    	}
    
    	CMatrix(const int & azeilen, const int & aspalten):fzeilen(azeilen), fspalten(aspalten)
    	{
    	   //zweidimensionales Array erzeugen
    	   fmatrix = new T *[azeilen]; 
    	   for(int i=0; i < azeilen; i++)
    	   fmatrix[i] = new T[aspalten];
    	}
    
    	//Destruktor
    	virtual ~CMatrix()
    	{
    	   cout << "Aufruf Destruktor!" << endl;
    	   for (int i = 0; i < fzeilen ; i++)
    	      delete fmatrix[i] ;
    	   delete fmatrix; 
    	}
    };
    

    Das Hauptprogramm dazu:

    #include "matrix.h"
    
    int main(int argc, char* argv[])
    {
       try
       {
          CMatrix<double> testmatrix(3,4);
          testmatrix.~CMatrix();
          return 0;
       }
       catch(CFehler & fehler)
       {
          fehler.ausgabe();
       }
    
    }
    

    Ich bekomme einen Fehler, das Programm bricht ab. Interesannterweise beim ZWEITEN Durchlauf des Destruktors!
    Wenn ich den try-catch Block entferne, wird der Destruktor auch zweimal aufgerufen, aber das Programm bricht nicht mit einem Fehler ab 😕
    Wieso wird überhaupt der Destruktor zweimal aufgerufen???

    Danke.



  • Wieso wird überhaupt der Destruktor zweimal aufgerufen???

    Weil testmatrix ein automatisches Objekt ist und du den Destruktor einmal explizit aufrufst.

    Du musst Destruktoren sogut wie nie explizit aufrufen (die Ausnahme ist für dich im Moment wohl noch uninteressant). C++ tut dies automatisch, wenn die Gültigkeit eines Objekts endet.

    Was du hingegen nicht vergessen darfst ist der Aufruf von delete, wenn du ein Objekt zuvor mit new angelegt hast.

    PS: Du solltest dringend nochmal das Kapitel "Gültigkeit/Lebensdauer von Objekten" im C++ Einsteigerbuch deiner Wahl nachlesen.



  • HumeSikkins schrieb:

    (die Ausnahme ist für dich im Moment wohl noch uninteressant)

    Das interessiert mich jetzt aber doch sehr :). Was ist denn die Ausnahme? Hat
    das was mit der Zerstoerung von Singletons zu tun, oder hab ich da grad was
    falsch im Kopf?

    mfg
    v R



  • Ja danke, ist logisch. Mein C++ ist ein wenig eingerostet, stelle ich gerade fest! 😋



  • @KeineAhnung78
    Dein Destruktor funktioniert eh nicht korrekt, so löscht man Arrays:

    //Destruktor
        virtual ~CMatrix()
        {
           cout << "Aufruf Destruktor!" << endl;
           for (int i = 0; i < fzeilen ; i++)
              delete [] fmatrix[i];  //EDIT: Jetzt aber
           delete [] fmatrix;  //Du löschst immerhin ein Array
        }
    


  • GPC schrieb:

    //Du löschst immerhin ein Array

    Das gilt aber auch für die Teilarrays -> "delete[] fmatrix[i];"



  • Danke 🙂



  • vR@uni schrieb:

    HumeSikkins schrieb:

    (die Ausnahme ist für dich im Moment wohl noch uninteressant)

    Das interessiert mich jetzt aber doch sehr :). Was ist denn die Ausnahme? Hat
    das was mit der Zerstoerung von Singletons zu tun, oder hab ich da grad was
    falsch im Kopf?

    mfg
    v R

    Die Ausnahme, die mir in diesem Zusammenhang einfällt, ist placement new.
    D.h. bei folgenden Code muss explizit der Dtor aufgerufen werden:

    class Foo
    {
       ...
    };
    
    int main()
    {
        void* raw_data = malloc(sizeof(Foo));
        Foo *obj = new (raw_data) Foo();
    
        // ...
    
        obj->~Foo();
        free(raw_data);
    }
    

    Ein Aufruf von Operator delete hätte hier fatale Folgen...

    Gruß Caipi


Anmelden zum Antworten