Reputation: 4532
I'm currently having trouble with a destructor of a class which contains a vector of objects. The application runs fine, however upon freeing the heap it throws an error.
Here is the code of my destructor:
~StaticNetwork(void) { // clear memory
for(vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); )
nodes.erase(iter++);
}
And nodes are being added to the network as follows:
if((temp = is_already_added(regex_d[1])) >= 0) // check if the src node has already been added
{
if((temp1 = is_already_added(regex_d[2])) >= 0) // check if the next_hop has already been added
{
nodes[temp]->add_n_vchannels(regex_d[5]);
nodes[temp]->add_next_hop(nodes[temp1]);
}
else // the next_hop has not been added
{
Node *anext_hop = new Node(regex_d[2]);
nodes[temp]->add_next_hop(anext_hop);
nodes[temp]->add_n_vchannels(regex_d[5]);
nodes.push_back(anext_hop); // add next hop
param.n_of_nodes++;
}
}
The network is comprised of pointers to the actual nodes.
Any help/suggestion/reference/(constructive)criticism will be greatly appreciated.
Upvotes: 1
Views: 838
Reputation: 60034
erase doesn't work as you expect: it removes the elements from the container, i.e. the pointers and not the pointed object. So you are leaking memory here.
Moreover, erase invalidates the iterators following the erased element(s), thus the test iter != nodes.end();
causes the error, as you increment the pointer past it.
Anyway, you can write the code as shown by David Rodríguez - dribeas.
Upvotes: 0
Reputation: 2854
You do not need to delete elements of vector manually, it will be done by vector itself. This is how destructors work: they call destructors of member objects of deleted object, so you don't have to worry about it.
Upvotes: 1
Reputation: 208466
Your iteration over the container is wrong. If the node
is a member of the class, then ignore it as the destructor of the vector will take care of it. If it is not a member and you really want to remove all elements, the simplest thing is calling node.clear()
(Note both are equivalent to your code, but they will leak the pointed memory if it should be managed by your class)
If the pointers are managed by your class, consider using smart pointers or specific pointer containers. Else the simplest loop to free all memory would be:
for ( std::vector<Node*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
delete *it;
Note that I did not modify the container itself, just the contained elements.
Upvotes: 2