简体   繁体   中英

Vector iterators incompatible: runtime error

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.

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.

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.

erase doesn't work as you expect: it removes the elements from the container, ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM