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