BUG : Destructor Called ErroneouslyLast reviewed: July 18, 1997Article ID: Q131148 |
1.00 1.50 1.51 1.52
WINDOWS
kbprg kbbuglist
The information to this article applies to :
SYMPTOMSThe destructor may be called for an object not created. This is not a common problem. It happens under a specific circumstances and the sample code in the "More Information" section demonstrates this behavior.
RESOLUTIONTwo workarounds are suggested in the sample code (see NOTE #1 and NOTE #2). These workarounds may change the intended behavior of the code.
STATUSMicrosoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.
MORE INFORMATION
Sample Code to Demonstrate Problem
/* No special compile options needed. */ #include <iostream.h> //AString int stringNumber = 0; void outputDebug(char *className, char *func, int number){
cout << "in " << className << "::" << className; cout << "() #" << number << " " << func << endl;} class AString{ public: AString(); AString(const AString &orig); virtual ~AString(); AString &operator=(const AString &orig);protected: int number;private: }; AString::AString() { number = ++stringNumber; outputDebug("AString", "copy1 constructor", number);} AString::AString(const AString &orig) { number = ++stringNumber; outputDebug("AString", "copy2 constructor", number);} AString::~AString() { outputDebug("AString", "Destructor", number);} AString &AString::operator=(const AString &orig) { outputDebug("AString", "operator=", number); return *this;}
//ACompressorclass ACompressor { public: ACompressor(AString& base); ~ACompressor();}; inline ACompressor::ACompressor(AString& baseObject){ outputDebug("ACompressor", "Constructor", 33);}inline ACompressor::~ACompressor(){ outputDebug("ACompressor", "Destructor",
33);} //APathclass APath : private AString{ public: APath() : AString(){} APath(char *) : AString(){} APath &operator =(const APath &path); //NOTE #1: if the line below is removed, the extraneous //call to AString::~AString() is not generated. inline operator AString() const { return *(AString *) this;}protected: private: APath(const APath &path); };APath &APath::operator =(const APath &orig) { //NOTE #2:if the line below is removed OR the one in the NOTE #1 is //removed, the extraneous AString::~AString() call is not //generated. ACompressor pc(*this); //NOTE #3: The line below generates a call to //APath::operator AString(). AString::operator=(orig); //NOTE #4: Extra AString::~AString() destructor call made here //Assembly listing shows the extra destructor call. return *this; } int main(){ char *filename = "c:\\someprog.exe"; APath exePath; exePath = filename; return 0;}
|
Additional reference words: 1.00 1.50 1.51 1.52 8.00 8.00c
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |