005
31.08.2004, 13:17 Uhr
virtual
Sexiest Bit alive (Operator)
|
@(un)wissender: Nein, das ist mnicht korrekt: im Constructor von Array im try Block wird die Exception geworfen, daher wird niemals der Destructor aufgerufen. Dh Code wie zB dieser ist immer Speicherleckverdächtig:
C++: |
class X { char* s1; char* s2; public: X() { s1 = new char[1024]; s2 = new char[1024]; } ~X() { delete[] s1; delete[] s2; } };
|
Wenn die Allocation von s1 gut geht, bei der Allokation von s2 was schief geht, wird nie und nimmer der dtor aufgerufen und daher leakt das Porgramm, weil s1 niemals freigegeben wird. Richtig wäre da schon eher:
C++: |
class X { char* s1; char* s2; public: X() :s1(NULL), s2(NULL) { try { s1 = new char[1024]; s2 = new char[1024]; } catch(...) { delete [] s1; delete [] s2; throw; } } ~X() { delete[] s1; delete[] s2; } };
|
Würde in Dudes Beispiel tatsächlich der dtor aufgerufen, dann würde das Programm mit 99% Prozentiger Wahrscheinlichkeit abstürzen, weil die Exception im ctor geworfen wird, bevor der member pType initialisiert wird. Würde nun der dtor aufgerufen, würde ein delete auf einen ungültigen Zeiger gemacht.
Hier noch ein kleines Beispiel zum Beleg meiner Aussage (ungetestet):
C++: |
#include <iostream> #include <stdexcept>
struct Throw { Throw() { std::cerr<<"ctor"<<std::endl; throw std::runtime_error("Error"); } ~Throw() { std::cerr<<"dtor"<<std::endl; } };
int main() try { Throw t; } catch(std::exception& e) { std::cerr<<e.what()<<std::endl; }
|
Ich würde die Ausgabe
erwarten. Falsch wäre die Ausgabe
-- Gruß, virtual Quote of the Month Ich eß' nur was ein Gesicht hat (Creme 21) Dieser Post wurde am 31.08.2004 um 13:18 Uhr von virtual editiert. |