rsc@erc3ba.UUCP (Rich Chomiczewski, AT&T - ERC, Princeton NJ) (03/05/88)
The following program blows the stack: // --------------------- Cut Here -------------------- #include <stream.h> class Point { int xc, yc; // x-y coordinates public: Point(int x =0, int y =0) { xc = x; yc = y; } int x() { return xc; } int y() { return yc; } Point operator+(Point p) { return Point(xc+p.xc, yc+p.yc); } }; ostream& operator<<(ostream& oo, Point p) { return oo << "(" << p.x() << "," << p.y() << ")"; } class Position { Point off; // offset is relative to (possibly null) ``to''. Position *to; public: Position() { off = Point(0,0); to = 0; } Position(Point p) { off = p; to = 0; } Position(Point p, Position pos) { off = p; to = &pos; } Point position() { return (to) ? off+to->position() : off; } }; ostream& operator<<(ostream& oo, Position p) { return oo << p.position(); } main() { Position a = Position(Point(1,1)); Position b = Position(Point(5,5), a); Position c = Position(Point(10,10), b); cerr << a; cerr << b; cerr << c; } // --------------------- Cut Here -------------------- One of the more difficult aspects of programming in c++ for me is the correct handling of assignment and initialization of classes (which I suspect is the root of the problem here). So, given the above declaration of class Position what is the "correct" definition of the member functions ``Position::Position(Position&)'' and ``Position::operator=(Position&)''? Thanks, Rich Chomiczewski (ihnp4!erc3ba!rsc)
fuchs@gmdka.UUCP (Harald Fuchs) (03/08/88)
in article <400@erc3ba.UUCP>, rsc@erc3ba.UUCP (Rich Chomiczewski, AT&T - ERC, Princeton NJ) says: > The following program blows the stack: > ... > class Position { > Point off; // offset is relative to (possibly null) ``to''. > Position *to; > public: > Position(Point p) { off = p; to = 0; } > Position(Point p, Position pos) { off = p; to = &pos; } > Point position() { return (to) ? off+to->position() : off; } > }; > main() > { > Position a = Position(Point(1,1)); > Position b = Position(Point(5,5), a); > Position c = Position(Point(10,10), b); > } The bug in this program is Position(Point p, Position pos) { off = p; to = &pos; } where you take the address of an object on the stack because pos is passed by value. Use reference passing (Position& pos) and the problem disappears. When you declare Position a = Position(Point(1,1)); the following functions are called: Position::Position (Point); // To make a temporary Position value Position::Position (Position&); // Initialisation of a by temp // See The Book p. 180 Position::~Position (); // To get rid of temp Since you didn't declare Position::Position (Position&), Cfront picks the default, namely bitwise copy. That happens to be ok in this context. Harald Fuchs UUCP: ...!uunet!mcvax!unido!gmdka!fuchs X.400: fuchs@karlsruhe.gmd.dbp.de