Assertion failed bei überladenem Operator, obwohl kein Code



  • Hallo zusammen.

    Ich schreibe gerade eine Klasse für mathematische Matrizen. Dafür habe ich den Multiplikations-Operator überladen. Bei der Multiplikation zweier Matrizen bekomm ich leider eine Meldung, dass eine Assertion fehlgeschlagen ist:

    http://files.planet-chewie.de/c++/assertion.jpg (Screenshot)

    Ich verwende MSVC++ in der Version 6.

    Das seltsame ist, dass effektiv gar kein Code ausgeführt wird.
    Ich rufe folgende Zeile auf (m1 und m2 sind Stackobjekte der Matrix-Klasse):

    Matrix m = m1 * m2;
    

    Der überladene Operator sieht folgendermaßen aus (Interface und Implementation):

    Matrix operator * (Matrix const m2);
    
    Matrix Matrix::operator * (Matrix const m2)
    {
    	/*//Exception auslösen, falls Größe ungleich
    	if (cols != m2.rows) {
    		throw new EInvalidDimensions();
    	}*/
    
    	//Matrix res(rows, m2.cols);
    	/*Matrix& m1 = (*this);
    
    	for(unsigned i = 1; i <= rows; i++) {
    		for(unsigned j = 1; j <= m2.cols; j++) {
    			//res(i,j) = 0;
    			for(unsigned k = 1; k <= cols; k++) {
    				res(i,j) += m1(i,k) * m2(k,j);
    			}
    		}
    	}*/
    
    	return NULL;
    
    }
    

    Der komplette Code bis auf die Rückgabe ist auskommentiert, und dennoch tritt der Fehler auf!

    Ich habe dazu leider als C++-Anfänger keine Ideen mehr, wenn jemand einen Rat hat, dann nur her damit!

    Danke im Voraus.



  • zeig doch ein vollständiges aber minimales programm.



  • Als Rückgabetyp hast du Matrix angegeben, NULL sieht nicht wie ein Objekt vom Typ Matrix aus 🙂



  • Nun, Du retournierst NULL, obwohl der Rückgabewert eine Matrix-Objekt ist. Also, das ist schon mal definitiv falsch!

    Beachte die Definition von NULL

    #define NULL    0
    

    Vollkommen korrekt wäre dieses Codefragment:

    Matrix::Matrix operator * (Matrix const &m2) 
    { 
             /*
                      ...
                      ...
             */
             Matrix tmp;
             return NULL;
    }
    


  • OK, stimmt, so wird man es besser nachvollziehen können.
    Die verlinkte ZIP-Datei enthält die von mir geschriebenen Dateien, aber ohne das MSVC-Gedöns.

    http://files.planet-chewie.de/c++/Matrix.zip



  • return 0 -> Konstruktor Matrix(0) wird implizit aufgerufen -> eventuell gibts da ein assert() im Konstruktor?

    MfG SideWinder



  • Konstruktor Matrix(0) ruft init(0, 0) auf und das versucht new double[0] aufzurufen und das gibt im Debug Modus eine assertion...



  • Mit explicit wäre das nicht passiert. 😉



  • Edit: war mist^^



  • OK, das mit der Rückgabe von NULL bzw. 0 war ein Griff ins Klo, das wollte ich nur machen, weil ich irgendwas zurückgeben wollte (das richtige Objekt zurückgeben klappte auch nicht).

    Ich hab meine Methode jetzt etwas abgeändert:

    Matrix Matrix::operator * (Matrix const m2)
    {
    	Matrix res(2);
    	return res;
    
    }
    

    Es wird also ein Objekt erstellt und zurückgegeben.
    Wenn ich durch den Einzelschrittmodus durchgehe, so tritt der Fehler bei der return-Anweisung auf 😡



  • Dann haperts im CopyCtor.

    MfG SideWinder



  • Der CopyCtor ist nicht definiert, d.h. der Compiler generiert Dir einen. Dabei wird der Zeiger auf data kopiert. Wird jetzt eine der beiden Matrizen zerstört, wird der Speicher freigegeben und die andere hat nur noch Müll.

    In Deinem Codestürck legst Du eine Matrix an, die beim Return in ein neues Objekt kopiert wird. Dann wird die erste Matrix zerstört und das zurückgegebene Objekt ist kaputt.



  • So.
    Ich weiß, ist schon länger her, aber am Copy-Konstruktor lags tatsächlich. Ich wusste einfach nicht, dass ich einen brauche 🙄

    Danke allen, die geantwortet haben.


Anmelden zum Antworten