🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.g++.bug
Article #1487

virtual destructors cause execution error for g++

#1487
From: "Douglas C. Schmidt"
Date: Sun, 09 Oct 1988 20:42
133 lines
3219 bytes
Hi,

  The following program causes a segmentation fault when executed on
Sun 3's and 4's.  The problem appears to be the virtual destructor:

virtual ~Node ( void ) .....

from class Node.  When this is omitted the program works fine.

Readers of the Journal of Object-Oriented Programming will recognize
this as Andrew Koenig's ``dynamic binding'' example from the
August/September issue.  This compiles and executes correctly when
compiled with CC.

----------------------------------------
#include <stream.h>

class Node {
   friend class Tree;
   friend ostream& operator << ( ostream&, const Tree& );

private:
   int Use;
   
protected:      
   Node ( void ) {
      Use = 1;
   }
   virtual void Print ( ostream& ) {
   }
   virtual ~Node ( void ) {  // if this is commented out the program runs ok
   }
};

class Tree {

private:   
   friend class Node;
   friend ostream& operator << ( ostream&, const Tree& );
   Node *Ptr;

public:
   Tree ( int );
   Tree ( char *, Tree );
   Tree ( char *, Tree, Tree );
   Tree ( const Tree& T ) {
      Ptr = T.Ptr; ++Ptr->Use;
   }
   ~Tree ( void ) {
      if ( --Ptr->Use == 0 ) {
         delete Ptr;
      }
   }
   void operator = ( const Tree& T ) {
      ++T.Ptr->Use;
      if ( --Ptr->Use == 0 ) {
         delete Ptr;
      }
      Ptr = T.Ptr;
   }
};

ostream& operator << ( ostream& Stream, const Tree& T ) {
   T.Ptr->Print ( Stream );
   return ( Stream );
}

class Int_Node : public Node {
   friend class Tree;
   
private:
   int Num;
   
   Int_Node ( int K ): Num ( K ) {
   }
   void Print ( ostream& Stream ) {
      Stream << Num;
   }
};

class Unary_Node : public Node {
   friend class Tree;

private:
   char *Operator;
   Tree Operand;
   
   Unary_Node ( char *Op, Tree T ): Operator ( Op ), Operand ( T ) {
   }

   void Print ( ostream& Stream ) {
      Stream << "(" << Operator << Operand << ")";
   }
};

class Binary_Node : public Node {
   friend class Tree;

private:
   char *Operator;
   Tree Left;
   Tree Right;
   
   Binary_Node ( char *Op, Tree T1, Tree T2 ): 
      Operator ( Op ), Left ( T1 ), Right ( T2 ) {
   }

   void Print ( ostream& Stream ) {
      Stream << "(" << Left << Operator << Right << ")";
   }
};

Tree::Tree ( int Num ) {
   Ptr = new Int_Node ( Num );
}

Tree::Tree ( char *Op, Tree T ) {
   Ptr = new Unary_Node ( Op, T );
}

Tree::Tree ( char *Op, Tree T1, Tree T2 ) {
   Ptr = new Binary_Node ( Op, T1, T2 );
}

main () {
   Tree T = Tree ( "*", Tree ( "-", 5 ), Tree ( "+", 3, 4 ) );
   
   cout << T << "\n";
   T = Tree ( "*", T, T );
   cout << T << "\n";   
}
----------------------------------------
Technical Details
Message-ID: <8810091342.aa26965@PARIS.ICS.UCI.EDU>
Path: arc1-ca.pugleaf.net!utzoo!telly!ddsw1!lll-winken!uunet!tut.cis.ohio-state.edu!ORION.CF.UCI.EDU!schmidt%blanche.ics.uci.edu

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!telly!ddsw1!lll-winken!uunet!tut.cis.ohio-state.edu!ORION.CF.UCI.EDU!schmidt%blanche.ics.uci.edu
From: schmidt%blanche.ics.uci.edu@ORION.CF.UCI.EDU ("Douglas C. Schmidt")
Newsgroups: gnu.g++.bug
Subject: virtual destructors cause execution error for g++
Message-ID: <8810091342.aa26965@PARIS.ICS.UCI.EDU>
Date: 9 Oct 88 20:42:51 GMT
Sender: daemon@tut.cis.ohio-state.edu
Distribution: gnu
Organization: GNUs Not Usenet
Lines: 132