4
Reading the book A tour of C++, in a section on memory leakage, when I came across 3 statements regarding the code below:
- The implementation of
Smiley
may fail to delete pointer tomouth
. - The attempt to delete the returned pointer from
read_shape()
can fail. - A variable of the type
Shape*
may fail to attempt to delete the object it points to.
Original text:
Experienced programmers will have noticed that I left open three Opportunities for mistakes:
• The implementer of Smiley may fail to delete the Pointer to Mouth.
• A user of read_shape() Might fail to delete the Pointer returned.
• The Owner of a container of Shape pointers Might fail to delete the Objects pointed to.
THE CODE BELOW DOES NOT COMPILE, IT IS JUST A REPRESENTATION OF THE BOOK TO UNDERSTAND THE PROBLEM.
class Shape
{
public:
virtual ~Shape() {}
};
class Circle : public Shape
{
public:
Circle(Point _center, int _rad) : center { _center }, rad { _rad }
{}
private:
Point center;
int rad;
};
class Smiley : public Circle
{
public:
Smiley(Point center, int rad) : Circle { center, rad }, mouth { nullptr }
{}
~Smiley()
{
delete mouth; // Referencia da primeira afirmação.
for (auto eye : eyes)
delete eye;
}
void set_mouth(Shape* _mouth)
{
mouth = _mouth;
}
private:
std::vector<Shape*> eyes;
Shape* mouth;
};
Shape* read_shape(std::istream& is)
{
//Read kind_of_shape
switch (kind_of_shape)
{
case Circle:
//Read p, r.
return new Circle { p, r };
break;
case Triangle:
//Read p1, p2, p3.
return new Triangle { p1, p2, p3 };
break;
case Smiley:
//Read {Point, int} int p, r.
Smiley∗ ps = new Smiley{p,r};
return ps;
break;
}
}
I realized that the problem of implementation was then in the Shape*
, I mean, a pointer to an abstract class, but I don’t understand what the problem is.
The text still describes:
Pointers to objects allocated in
free store
¹ are dangerous: an old Pointer' ² should not be used to represent a property.
Original text:
... pointers to Objects allocated on the free store is Dangerous: a ːː Plain old Pointer'' should not be used to represent Ownership.
The question that remains is: Because the command delete
in a type variable Shape*
maybe I’ll fail? .
[1][2] I don’t know a proper translation.
The solution to this problem presented by the text is using std::unique_ptr<Shape>()
in place of Shape*
.
So in the first case, I made the confusion because I could not translate the text the right way?
– Henrique Hott
And why "Smiley implementer might fail to erase pointer to Mouth" if Smiley destructor invokes delete Mouth? Smiley’s destroyer shouldn’t be called once he’s out of the scope?
– Henrique Hott
"See the Shape destructor code: first solve case 1 and then case 3." Shape’s destructor is empty, as it solves something?
– Henrique Hott
That’s the point:
Shape
created no problem.Smiley
introduced a vulnerability. It’s not the end of the world. And that’s why destructors begin to be invoked by the inner class. And the author talks about hypotheses. "If" the implementor fails. In this example it did not fail. And I misspelled: I was referring to the destructor ofSmiley
that does the expected and in the right order. Sorry. I will correct– arfneto