ID: Q131148
1.00 1.50 1.51 1.52 WINDOWS kbprg kbbuglist
The information to this article applies to :
The 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.
Two workarounds are suggested in the sample code (see NOTE #1 and NOTE #2). These workarounds may change the intended behavior of the code.
Microsoft 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.
/* 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;
}
//ACompressor
class ACompressor {
public:
ACompressor(AString& base);
~ACompressor();
};
inline ACompressor::ACompressor(AString& baseObject){
outputDebug("ACompressor", "Constructor", 33);}
inline ACompressor::~ACompressor(){ outputDebug("ACompressor",
"Destructor",
33);}
//APath
class 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 KBCategory: kbprg kbbuglist KBSubcategory: CPPIss
Keywords : kb16bitonly kbCompiler kbCPPonly kbVC kbbuglist
Version : 1.00 1.50 1.51 1.52
Platform : WINDOWS
Last Reviewed: July 22, 1997