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