Q121216: BUG: Vector Delete Calls Exported Destructor Only Once
Article: Q121216
Product(s): Microsoft C Compiler
Version(s): 1.0,1.5,2.0,4.0,4.1,4.2,5.0,6.0
Operating System(s):
Keyword(s): kbCompiler kbVC100bug kbVC150bug kbVC200bug kbVC400bug kbVC410bug kbVC420bug kbVC500bug
Last Modified: 17-FEB-2002
-------------------------------------------------------------------------------
The information in this article applies to:
- Microsoft C/C++ Compiler (CL.EXE), used with:
- Microsoft Visual C++ for Windows, 16-bit edition, versions 1.0, 1.5
- Microsoft Visual C++, 32-bit Editions, versions 1.0, 2.0, 4.0, 4.1, 4.2, 5.0, 6.0
- Microsoft Visual C++.NET (2002)
-------------------------------------------------------------------------------
SYMPTOMS
========
A call to the vector delete operator on a class defined in a DLL calls the
destructor for the object only once. This problem occurs only if the destructor
is virtual and the DLL itself does not reference the vector memory allocation
functions (new [] or delete []).
CAUSE
=====
The code generated by the compiler to perform vector deleting of objects is done
by generating a call to an internal function. This internal function is
generated by the compiler.
The problem is due to an incorrect compiler optimization. The compiler assumes
that if a module (EXE or DLL) never makes reference to the vector memory
operators, then the internal function that handles the vector deleting is not
needed. This is a valid optimization for an EXE but not for a DLL.
Therefore, this statement:
delete [] pClass
Ends up being basically the same as:
delete pClass
RESOLUTION
==========
To work around this problem, you must force your DLL to reference the vector
deleting destructor. The memory allocation functions don't actually need to be
called. The compiler just needs to see them. This can be done by generating a
dummy function that is never called but that is linked in to the DLL. For
example:
void ForceVectors()
{
CMyClass *pClass = new CMyClass[2];
CMyClass *pOtherClass = new CMyOtherClass[2];
};
static (void *pFunc)() = ForceVectors;
The reference to the static variable initialization (pFunc) forces the function
ForceVectors to be linked in. This then forces the DLL to have the vector
deleting destructors for the classes (CMyClass and CMyOtherClass). Place this
code in any module in your DLL.
STATUS
======
Microsoft has confirmed this to be a bug in the products listed at the beginning
of this article. This bug was corrected in Visual C++ version 5.0 to generate
correct behavior in the case where the entire class is exported. The bug (and
workaround) remains for the case where the class is not exported, but individual
class members are exported.
Additional query words:
======================================================================
Keywords : kbCompiler kbVC100bug kbVC150bug kbVC200bug kbVC400bug kbVC410bug kbVC420bug kbVC500bug kbVC600bug
Technology : kbVCsearch kbAudDeveloper kbCVCComp
Version : :1.0,1.5,2.0,4.0,4.1,4.2,5.0,6.0
Issue type : kbbug
Solution Type : kbfix
=============================================================================
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.
Copyright Microsoft Corporation 1986-2002.