2012-04-01 12 views
1

Ich habe derzeit Probleme mit einem Destruktor einer Klasse, die einen Vektor von Objekten enthält. Die Anwendung läuft zwar einwandfrei, beim Freigeben des Heap-Speichers wird jedoch ein Fehler ausgegeben. HierVector iterators inkompatibel: Laufzeitfehler

ist der Code meines destructor:

~StaticNetwork(void) { // clear memory 
    for(vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end();) 
     nodes.erase(iter++); 
} 

Und Knoten an das Netzwerk werden wie folgt hinzugefügt:

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++; 
       }  
      } 

Das Netzwerk besteht aus Zeiger auf die aktuellen Knoten.

Jede Hilfe/Anregung/Referenz/(konstruktive) Kritik wird sehr geschätzt werden.

Antwort

2

Ihre Iteration über den Container ist falsch. Wenn die node ein Mitglied der Klasse ist, dann ignorieren Sie es, da der Destruktor des Vektors dafür sorgen wird. Wenn es kein Mitglied ist und Sie wirklich alle Elemente entfernen möchten, ist der einfachste Aufruf node.clear() (Hinweis: beide entsprechen Ihrem Code, aber sie werden den angegebenen Speicher verlieren, wenn es von Ihrer Klasse verwaltet werden sollte)

Wenn die Zeiger von Ihrer Klasse verwaltet werden, sollten Sie Smartpointer oder bestimmte Pointercontainer verwenden. Else die einfachste Schleife alle Speicher frei wäre:

for (std::vector<Node*>::iterator it = nodes.begin(); it != nodes.end(); ++it) 
    delete *it; 

Bitte beachte, dass ich nicht den Behälter selbst hat ändern, nur die enthaltenen Elemente.

+0

Danke. Das hat den Job gemacht. – Sebi

+0

Es sollte auch beachtet werden, dass der Grund für den Fehler, den Sie erhielten, war, dass vector.erase Ihren Iterator ungültig gemacht hat. –

+1

@Sebi: als Randnotiz - wenn Sie tatsächlich Vektorelemente in einer Schleife löschen möchten, die von einem Iterator abhängt, können Sie den nächsten gültigen Iterator nach der Operation 'radier()' mit 'iter = nodes.esase (iter) '. Um es klar zu sagen - das ist in dieser Situation nicht nützlich, aber in Zukunft, wenn Sie jemals 'nodes.erase (iter ++)' machen wollen, sollten Sie stattdessen den Rückgabewert von 'vector :: erase()' verwenden. –

1

Sie müssen Elemente des Vektors nicht manuell löschen, es wird durch den Vektor selbst erfolgen. So funktionieren Destruktoren: Sie rufen Destruktoren von Mitgliedsobjekten des gelöschten Objekts auf, sodass Sie sich keine Gedanken darüber machen müssen.

0

erase funktioniert nicht wie erwartet: es ist das Objekt Elemente aus dem Behälter, das heißt die Zeiger und nicht das spitze entfernt. Sie verlieren also hier die Erinnerung.

Außerdem löscht Löschen die Iteratoren nach dem gelöschten Element (s), so verursacht der Test iter != nodes.end(); den Fehler, wie Sie den Zeiger darüber hinaus erhöhen.

Wie auch immer, Sie können den Code schreiben, wie von David Rodríguez - dribeas gezeigt.