horstman@mathcs.sjsu.edu (Cay Horstmann) (04/20/91)
Here is a truly annoying bug with BC++ 2.0 which took me days to nail
down. When defining an operator= inline, there was a memory leak which
disappeared when making it into a regular function call. The circumstances
look weird from the distillation below but they aren't so uncommon
in practice.
I sent a copy to bugs@borland.com.
If you have a memory leak with BC++, watch those destructors and stay
away from inline functions defined in the class definition. (Defining
them inline OUTSIDE the class definition is ok!!!)
Cay
/****************************************************************************
This file illustrates a bug with Borland C++ Version 2.0. Here are the
ingredients:
- A class X with constructors, copy constructor, destructor, operator=
- A class Y having a member of class X
- An operator= in class Y calling the operator= in class X
Here is the symptom:
- If Y::operator= is inline in the class declaration, the program fails
to call a destructor. (Compile with the OK flag undefined.)
- If Y::operator= is not in the class declaration, the program works
correctly (compile with -DOK), even when declared inline !!!
I have not tried to pare this down any further. This is the condensation
from a largish piece of real code which had a memory leak. It is possible
that not all the ingredients present here are necessary for causing the
error.
****************************************************************************/
#include <stdio.h>
class X
{ int x;
public:
X() { x = 0; printf( "Created X at %p\n", this ); }
X(int n) { x = n; printf( "Created X at %p\n", this ); }
X(const X& b) { x = b.x; printf( "Created X at %p\n", this ); }
X& operator=( const X& b ) { x = b.x; return *this; }
~X() { printf( "Deleted X at %p\n", this ); }
};
class Y
{ X x;
public:
Y() : x(0) {}
Y( int n ) : x(n) {}
#ifdef OK
Y& operator=( const Y& b );
#else
Y& operator=( const Y& b ) { x = b.x; return *this; }
#endif
};
#ifdef OK
// inline also works
Y& Y::operator=( const Y& b ) { x = b.x; return *this; }
#endif
main()
{ Y y;
y = 4;
}