A mate of mine told me, I've a memory leak in this code
Base
{
public:
vector<Foo*> fooes;
};
Derived : public Base
{
public:
Derived ( )
{
for ( int i = 0 ; i < 10 ; i++ )
{
this.fooes.push_back ( new Foo() );
}
};
};
But he is a very busy man and he can not help me, so I ask you, where is the memory leak? And how do I fix it? As I understand it, the memory leak is that I do not delete objects, created by new Foo()
, so I just can add a destructor to Base
, and clear fooes
vector, right?
Base
{
public:
vector<Foo*> fooes;
~Base ( )
{
this->fooes.clear();
};
};
The question is:
Is this a correct memory leak fix?
Will the destructor of
Base
be called before the destructor of Derived, or not?Will the
fooes
vertor be deleted automatically while deletingBase
or I must delete all members of the class manually?
1) Is this a correct memory leak fix?
No, you have to iterate through the elements and manually delete
them.
2) Will the destructor of Base be called before the destructor of Derived, or not?
No (assuming you're deleting a Derived
object).
3) Will the fooes vector be deleted automatically while deleting Base or I must delete all members of the class manually?
Yes & no. The vector itself will be deleted because it is managed automatically, its members will not:
~Base ( )
{
for ( size_t i = 0 ; i < fooes.size() ; i++ )
delete fooes[i];
};
You should have a delete
and delete[]
for every new
and new[]
respectively.
A better alternative to all this is using smart pointers.
You need to iterate over all your pointers in the vector and delete them before clearing it. The vector will clear the pointers, but it will not clear the memory they point to unless you do it yourself or change your vector to use something like a shared_ptr. If your vector were a vector of objects, then you would not have a memory leak, but since the elements are pointers that have been allocated via new
you will need to release that memory - the vector will not automatically do it for you.
There is no memory leak in the code example, just a class definition. If a program creates an object of type Derived
and destroys it, there will probably (see below) be a memory leak. But if a program creates an object of type Derived
, destroys all the Foo
objects that it holds, then deletes the original object, there will probably not be a memory leak.
Memory leaks can only rarely be analyzed in isolation; they are properties of a whole program. This class could be modified to delete the Foo
objects, but that could impose a new design constraint that wasn't intended. For example, Foo
objects might register themselves in an internal container, with a requirement that all such objects persist until the end of the program; given that requirement, deleting the objects in the destructor of Derived
would be wrong.
Now, that's all largely hypothetical; I wouldn't complain about someone enhancing the destructor of Derived
to delete all the Foo
objects -- it's probably the right thing to do. But there's always a bit of a doubt...
A mate of mine told me, I've a memory leak in this code
Base
{
public:
vector<Foo*> fooes;
};
Derived : public Base
{
public:
Derived ( )
{
for ( int i = 0 ; i < 10 ; i++ )
{
this.fooes.push_back ( new Foo() );
}
};
};
But he is a very busy man and he can not help me, so I ask you, where is the memory leak? And how do I fix it? As I understand it, the memory leak is that I do not delete objects, created by new Foo()
, so I just can add a destructor to Base
, and clear fooes
vector, right?
Base
{
public:
vector<Foo*> fooes;
~Base ( )
{
this->fooes.clear();
};
};
The question is:
Is this a correct memory leak fix?
Will the destructor of
Base
be called before the destructor of Derived, or not?Will the
fooes
vertor be deleted automatically while deletingBase
or I must delete all members of the class manually?
1) Is this a correct memory leak fix?
No, you have to iterate through the elements and manually delete
them.
2) Will the destructor of Base be called before the destructor of Derived, or not?
No (assuming you're deleting a Derived
object).
3) Will the fooes vector be deleted automatically while deleting Base or I must delete all members of the class manually?
Yes & no. The vector itself will be deleted because it is managed automatically, its members will not:
~Base ( )
{
for ( size_t i = 0 ; i < fooes.size() ; i++ )
delete fooes[i];
};
You should have a delete
and delete[]
for every new
and new[]
respectively.
A better alternative to all this is using smart pointers.
You need to iterate over all your pointers in the vector and delete them before clearing it. The vector will clear the pointers, but it will not clear the memory they point to unless you do it yourself or change your vector to use something like a shared_ptr. If your vector were a vector of objects, then you would not have a memory leak, but since the elements are pointers that have been allocated via new
you will need to release that memory - the vector will not automatically do it for you.
There is no memory leak in the code example, just a class definition. If a program creates an object of type Derived
and destroys it, there will probably (see below) be a memory leak. But if a program creates an object of type Derived
, destroys all the Foo
objects that it holds, then deletes the original object, there will probably not be a memory leak.
Memory leaks can only rarely be analyzed in isolation; they are properties of a whole program. This class could be modified to delete the Foo
objects, but that could impose a new design constraint that wasn't intended. For example, Foo
objects might register themselves in an internal container, with a requirement that all such objects persist until the end of the program; given that requirement, deleting the objects in the destructor of Derived
would be wrong.
Now, that's all largely hypothetical; I wouldn't complain about someone enhancing the destructor of Derived
to delete all the Foo
objects -- it's probably the right thing to do. But there's always a bit of a doubt...
0 commentaires:
Enregistrer un commentaire