Article: Q132893
Product(s): Microsoft C Compiler
Version(s): 2.0 2.1 4.0 4.2 5.0
Operating System(s):
Keyword(s): kbcode kbCodeGen kbCompiler kbCPPonly kbVC
Last Modified: 30-JUL-2001
-------------------------------------------------------------------------------
The information in this article applies to:
- The C/C++ Compiler (CL.EXE), included with:
- Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1, 4.0
- Microsoft Visual C++, 32-bit Enterprise Edition, version 4.2
- Microsoft Visual C++, 32-bit Professional Edition, version 4.2
- Microsoft Visual C++, 32-bit Enterprise Edition, version 5.0
- Microsoft Visual C++, 32-bit Professional Edition, version 5.0
-------------------------------------------------------------------------------
SYMPTOMS
========
Memory that is dynamically allocated in a constructor can be orphaned when an
exception is thrown in the constructor.
CAUSE
=====
When inside a constructor, the object is partially constructed, so the
destructor is not called. While automatic data is freed during stack unwinding,
memory that is dynamically allocated is not properly cleaned up.
RESOLUTION
==========
Two-phased construction of objects resolves this problem (see the following code
sample). This way, the object is fully constructed, so when it is deleted,
cleanup is handled correctly.
Sample Code
-----------
The following sample code shows both single- and two-phased construction for a
class.
/* Compile options needed: /MT /GX
*/
// Change the following line into a comment to show the problem:
#define TWO_PHASED_CONSTRUCTION
// Include the MFC debug memory allocation functions. You will see the
// memory leaks reported by MFC when the application terminates when you
// run the program in the Visual C++ debugger.
#include "afx.h"
#define new DEBUG_NEW
class A
{
char *x;
public:
#ifndef TWO_PHASED_CONSTRUCTION
A() // This code doesn[ASCII 146]t clean up.
{
x = new char[10]; // x will be orphaned.
throw int(1);
}
#else
A() // This code cleans up fine.
{
// Initialize automatic variables here.
}
void Create()
{
// Initialize dynamic members here.
x = new char[10];
throw int(1);
}
#endif
~A()
{
delete [] x;
}
};
void main()
{
A *a;
try
{
a=0;
a=new A;
// Do memory allocation in Create() when doing two-phased construction.
#ifdef TWO_PHASED_CONSTRUCTION
a-<Create();
#endif
}
catch(int)
{
delete a;
}
}
Additional query words: 9.0 9.1 9.00 9.10
======================================================================
Keywords : kbcode kbCodeGen kbCompiler kbCPPonly kbVC
Technology : kbVCsearch kbAudDeveloper kbCVCComp
Version : 2.0 2.1 4.0 4.2 5.0
Issue type : kbprb
=============================================================================