BUG : Destructor Called Erroneously

Last reviewed: July 18, 1997
Article ID: Q131148
1.00 1.50 1.51 1.52 WINDOWS kbprg kbbuglist

The information to this article applies to :

  • The Microsoft C/C++ Compiler (CL.EXE) incuded with: Microsoft Visual C++ for Windows, versions 1.0, 1.5, 1.51, 1.52

SYMPTOMS

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.

RESOLUTION

Two workarounds are suggested in the sample code (see NOTE #1 and NOTE #2). These workarounds may change the intended behavior of the code.

STATUS

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.

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;
}

//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 : CPPIss kb16bitonly kbbuglist kbprg
Version : 1.00 1.50 1.51 1.52
Platform : WINDOWS


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 18, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.