[comp.lang.c++] Simple Question for C++ Experts

leo@duttnph.tudelft.nl (Leo Breebaart) (10/10/90)

I am troubled by an Annoying Problem.
This problem (slightly simplified) boils down to this: I am creating a 
binary (parse-)tree structure with operators in the inner nodes, and 
descriptor pointers in the leaves.

The constructor: 

    Expr(int leaf)

creates an appropriate nil-ary leaf-expression, containing information
about, in this case, an integer.

The constructor:

    Expr(String& op, Expr& left, Expr& right)

creates a binary internal node.

Thus, I am allowed to say 'new Expr(5)' in my code. What I now want to be 
able to do is to say 'new Expr("+", 5, 6)' as well, and this seems to be
impossible - it causes memory faults during run-time.

If instead I use the verbose 'new Expr("+", *new Expr(5), *new Expr(6))'
then everything works as I want it to.

If I understand C++ internal workings correctly, then the short version
gets expanded to 'new Expr("+", Expr(5), Expr(6))', i.e. references to
temporary storage are passed to my constructor, causing the memory
faults later on when the temporaries have been deleted.

1] Is my analysis of the problem correct?

2] Whether it is or not: can I achieve the effect I want in a simple way?

I apologize beforehand if this turns out to be too trivial or just 
a silly error on my part, but I am getting a bit desperate, and I can't
find the answer in any of my references (Stroustrup, Lippman, Gorlen).

All mailed/posted advice and suggestions welcome...


--
Leo Breebaart  (leo @ duttnph.tudelft.nl)

dsouza@optima.cad.mcc.com (Desmond Dsouza) (10/13/90)

In article <leo.655570723@duttnph> leo@duttnph.tudelft.nl (Leo Breebaart) writes:
------------------------------------------------------------
   The constructor: 

       Expr(int leaf)

   creates an appropriate nil-ary leaf-expression, containing information
   about, in this case, an integer.

   The constructor:

       Expr(String& op, Expr& left, Expr& right)

   creates a binary internal node.

   Thus, I am allowed to say 'new Expr(5)' in my code. What I now want to be 
   able to do is to say 'new Expr("+", 5, 6)' as well, and this seems to be
   impossible - it causes memory faults during run-time.

   If instead I use the verbose 'new Expr("+", *new Expr(5), *new Expr(6))'
   then everything works as I want it to.

   If I understand C++ internal workings correctly, then the short version
   gets expanded to 'new Expr("+", Expr(5), Expr(6))', i.e. references to
   temporary storage are passed to my constructor, causing the memory
   faults later on when the temporaries have been deleted.

   1] Is my analysis of the problem correct?

   2] Whether it is or not: can I achieve the effect I want in a simple way?

------------------------------------------------------------
I believe your analysis is right. 

You need to decide who (caller/callee) is responsible for creating the
long-lived versions of expressions.

Assuming the callee is responsible (i.e. transparent to the caller)
Option 1:
       Expr(String& op, Expr& left, Expr& right) {
         // make copies of arguments using "new"
	 // you need a "copy constructor" Expr::Expr(const Expr&)
	 // .. rest of stuff
	 }

Option 2:
   Replace:  Expr(String& op, Expr& left, Expr& right)
   with
    Expr(String& op, int i, int j) {
      // use new Expr(i), new Expr(j)
      //...
      }

   This version avoids the overhead of temporaries Exprs.

--- 

Desmond.
--

-------------------------------------------------------------------------------
 Desmond D'Souza, MCC CAD Program | ARPA: dsouza@mcc.com | Phone: [512] 338-3324
 Box 200195, Austin, TX 78720 | UUCP: {uunet,harvard,gatech,pyramid}!cs.utexas.edu!milano!cadillac!dsouza