1

Aufgrund einiger Verrücktheit musste ich auf einer neuen Installation von Win7 Pro auf Microsoft Visual Studio 2010 Ultimate aktualisieren. Ich habe den Code auf die Struktur reduziert und was im Allgemeinen passiert. Ich habe gehört, dass dies ein Fehler in VS2010 in ihrer STL-Implementierung sein könnte, und wenn ja, bin ich auf der Suche nach einem Workaround. (EDIT: Mein ursprünglicher Code funktionierte gut in Visual Studio 2008)Visual Studio 2010, C++, "Vektor-Iteratoren inkompatibel" während vector.clear()

Hier ist die Header-Datei:

#include <iostream> 
#include <vector> 
using namespace std; 

class ChildClass //partition function for each 
{ 
public: 
    ChildClass(); 
    void Clear(void); 
    vector<double> childrenvars; 
    void PrintChildren(void); 
    //long list of other variables 
}; 
class ParentClass 
{ 
    public: 
    ChildClass variable; 
    //other variables 
    ParentClass(); 
    ~ParentClass(); 
}; 

Und hier ist die Quelldatei:

#include "source.h" 

ChildClass::ChildClass() 
{ 
    Clear(); 
} 
void ChildClass::Clear(void) 
{ 
    childrenvars.clear(); 
    return; 
} 
void ChildClass::PrintChildren(void) 
{ 
    cout << endl; 
    for(unsigned int i=0; i<childrenvars.size(); i++) 
     cout << childrenvars[i] << " "; 
} 
ParentClass::ParentClass() 
{ 
    this->~ParentClass(); 
} 
ParentClass::~ParentClass() 
{ 
    this->variable.childrenvars.clear(); 
} 

int main(void) 
{ 
    ParentClass* ParVar = new ParentClass[5]; 
    for(unsigned int numiter = 0; numiter < 3; numiter++) 
    { 
     for(unsigned int i=0; i<5; i++) 
     { 
      for(unsigned int j=0; j<i; j++) 
       ParVar[i].variable.childrenvars.push_back(j); 
      ParVar[i].variable.PrintChildren(); 
     } 
     for(unsigned int i=0; i<5; i++) 
      ParVar[i].variable.Clear(); 
    } 
    delete [] ParVar; 
    int wait; 
    std::cin >> wait; 
    return(0); 
} 

in Release Kompilieren gibt eine vorhersagbare und funktional:

(blank) 
0 
0 1 
0 1 2 
0 1 2 3 

0 
0 1 
0 1 2 
0 1 2 3 

0 
0 1 
0 1 2 
0 1 2 3 

im Debug-Modus Kompilieren gibt:

(blank) 
0 
0 1 
0 1 2 
0 1 2 3 

Debug Assertion Failed... vector iterators incompatible. 

Es ist auf das erste Mal versagt es die .Clear() Funktion aufruft. Dies tritt auch auf, wenn die clear for-Schleife geändert wird, um bei 1,2 usw. zu starten. Der Fehler scheint sich als .clear() zu ergeben .erase (begin(), end()). Es hasst es wirklich, wenn nichts in den Vektor eingefügt wurde und es bereits leer ist. Interessanterweise ist das, was ich unter den Autos sehe, wenn die Löschschleife beim Löschen bei 2 beginnt (const_iterator _First_arg, const_iterator_Last_arg).

_First_arg = 0, wie erwartet.

_Last_arg = -2,53 ... e-098

this:

Größe: 2

Kapazität: 2

0: 0,0000 ...

1: 1.000 ....

Der erste Vektor beginnt um: 0x002648e8 Der letzte Vektor beginnt bei: 0x002648f8 (obwohl ich denke, dass aufgrund des Endes(), dies tatsächlich eins nach dem letzten ist, was bei 8-Byte-Doppelpunkten sinnvoll wäre).

Abgesehen von den Präprozessordefinitionen und der Einstellung _ITERATOR_DEBUG_LEVEL = 0, um diese "Funktionen" auszuschalten (ich würde gerne wissen, ob ich versehentlich etwas vermassle), hat irgendjemand irgendwelche Ideen, was die eigentliche Ursache ist und ist Wie behebt man das? Obwohl ich einige überflüssige Clears habe, glaube ich nicht, dass dies die Ursache für dieses Problem sein würde. Vor allem, wenn man bedenkt, dass der Code überhaupt nicht zu den Destruktoren gelangt.

Vielen Dank im Voraus!

~ Dan

Antwort

1

nicht sicher, was die Absicht hier ist, aber wenn man this->~ParentClass(); entfernen funktioniert es.

+0

Nun, in diesem Code ist es sinnlos. Im echten Code habe ich immer wieder dieselben Dinge für den Konstruktor und die Destruktoren geschrieben. Ich mache immer null/null Dinge aus, nur um sicher zu sein und dachte mir einfach, es wäre einfacher, einen Funktionsaufruf zu tippen, anstatt ... Paste mit einem Trackpad zu kopieren. Scheitern. Aber ja ... das hat dieses Beispielproblem behoben. Ich muss sehen, ob es alles für meine Forschung behebt! Ich bin optimistisch. Danke, Tonnen. Ich habe mir für ein paar Tage den Kopf zerbrochen. –

+2

Sie können niemals einen Destruktor selbst nennen. Es "klärt" keine Daten, wie du es sagst, es zerstört es. Es löscht Objekte, löscht Speicher und macht Zeiger ungültig. Der einzige Grund, warum Sie einen Destruktor selbst aufrufen können, ist im Fall von In-Place New. Sie sollten einige C++ - Grundlagen lesen. Sie sollten eine separate Funktion namens "Zurücksetzen" oder etwas erstellen, das ein Soft-Reset des Objekts durchführt und es in einem nutzbaren Zustand belässt. –

2
ParentClass::ParentClass() 
{ 
    this->~ParentClass(); 
} 

A destructor ist keine normale Funktion, es ist eine besondere Funktion ist. Wenn Sie den Destruktor für ein Objekt aufrufen, wird es vollständig zerstört, einschließlich aller seiner Basen und Elemente. Hier zerstören Sie das ParentClass Objekt, bevor es vollständig erstellt wurde.Jeder Versuch, das Objekt zu verwenden, verursacht wahrscheinlich Probleme, wie z. B. das Problem, das durch die angezeigte Fehlermeldung angezeigt wird.

Wenn Sie Code zwischen dem Destruktor und einer anderen Funktion teilen möchten, sollten Sie aber den Code in einer separaten Funktion eingeben und diesen vom Destruktor und der anderen Funktion aufrufen. In fast jedem Anwendungscode sollten Sie niemals einen Destruktor explizit aufrufen müssen.

std::vector ist standardmäßig leer konstruiert und reinigt auf Zerstörung, so der ChildClass Konstruktor und der ParentClass und Destruktor alle redundanten in Ihrem Beispiel sind und weggelassen werden können.

+0

so grundsätzlich Destruktor wird aufgerufen, wenn Sie "Objekt löschen" schreiben –