C ++ Löschen eines Listenelements beim Iterieren: Standardlösung funktioniert nicht?

8

Hier ist mein Problem. Ich habe viele vorherige Fragen darüber gelesen, wie man ein Mitglied einer Liste löscht, während man darüber iteriert, und ich habe die verschiedenen Lösungen, die die Antworten vorgeschlagen haben, ausprobiert. Es kommt vor, dass sie nicht zu funktionieren scheinen. Ich habe eine Liste von Klassen dieser Art:

%Vor%

Der Konstruktor und der Destruktor sind die folgenden

%Vor%

Jetzt die Liste

%Vor%

ist als Mitglied einer anderen Klasse definiert. Nun, wenn das Element moltechnicity null ist (berechnet über eine andere Funktion), muss ich das Mitglied dynamisch aus der Klasse entfernen, und so mache ich es:

%Vor%

Erhalte den folgenden Fehler zur Laufzeit:

  

prog (22332) malloc: * Fehler für Objekt 0x7f838ac03a60: Zeiger ist   Freigegeben wurde nicht zugeordnet   * Setzen Sie einen Breakpoint in malloc_error_break, um den Debug-Trap zu debuggen: 6

Siehst du den Fehler? Vielen Dank für Ihre Hilfe!! Wenn Sie mehr Code benötigen, lassen Sie es mich wissen.

    
Simone Bolognini 20.04.2015, 19:50
quelle

2 Antworten

3

Sie sollten copy constructor implementieren, da die Liste dies intern verwendet. Die Kopie muss ausgeführt werden, wenn Sie Code wie: list.push_back(Walker(5)); ausführen. Das temporäre Objekt muss verschoben oder in die Liste kopiert werden. Der Standardkopiekonstruktor kopiert nur Zeiger, sodass der Destruktor zweimal den gleichen Speicher freigibt.

Auch bewegen semantische in diesem Fall ist genug: Fügen Sie diesen Konstruktor zu Ihrem Code hinzu:

%Vor%

und entfernen Sie den Kopierkonstruktor (oder implementieren Sie ihn ordnungsgemäß):

%Vor%

Wenn Sie Zeiger verwenden und Speicher zuweisen, sollten Sie die Regel drei kennen:

  

Die Regel der Drei (auch bekannt als das Gesetz der Großen Drei oder Das Große   Drei) ist eine Faustregel in C ++ (vor C ++ 11), die behauptet, dass wenn   Eine Klasse definiert eine der folgenden sollte es wahrscheinlich explizit   Definieren Sie alle drei:

     

Destruktor

     

Kopierkonstruktor

     

Kopierzuweisungsoperator

    
AdamF 20.04.2015, 19:58
quelle
8

Das Problem hat nichts mit der Verwendung von std::list zu tun, aber es ist im Destruktor:

%Vor%

Sie haben über new[] , nicht new zugewiesen, daher müssen Sie delete[] nicht delete :

verwenden %Vor%

Live-Demo

Beachten Sie auch, dass molteplicity und weight niemals initialisiert werden und daher eine beliebige Zahl enthalten können (wahrscheinlich anders als 0 ).

Nach diesen Änderungen programmieren Sie kompiliert und laufen perfekt.

Beachten Sie auch, dass new und delete aus guten Gründen in der C ++ - Community generell verpönt sind. Verwenden Sie intelligente Zeiger oder Container und folgen Sie im Allgemeinen der Regel von null .

Und schließlich können Sie mit std::list::remove_if eine sauberere Lösung erreichen. Wenn Sie diesen Tipps folgen, erhalten Sie etwas wie folgt:

%Vor%

und verwendet als:

%Vor%

Live-Demo

Was sowohl lesbarer als auch korrekter ist.

    
Shoe 20.04.2015 19:56
quelle

Tags und Links