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