2009-05-13 22 views
3

Ich habe eine Klasse (foo), die einen Vektor enthält.C++: Das erste Element des Vektors "korrumpieren"

Wenn ich wie so in den Vektor über die Elemente versuchen Iterieren:

for(vector<random>::iterator it = foo.getVector().begin(); 
     it != foo.getVector().end(); ++it) { 
    cout << (*it) << endl; 

} 

Das erste Element ist immer beschädigt und gibt Datenmüll.

Wenn jedoch, wie etwas zu tun:

vector<random> v = foo.getVector(); 
for(vector<random>::iterator it = v.begin(); 
      it != v.end(); ++it) { 
     cout << (*it) << endl; 

} 

Alles scheint zu funktionieren. Gibt es ein "Gotcha", von dem ich nichts weiß?

Ich habe auch versucht, Cout zu tun < < foo.getVector() [0] < < endl; außerhalb der Schleife, aber das scheint in Ordnung zu sein.

Danke.

Edit:

Hier ist meine Header-Datei:

#ifndef HITS 
#define HITS 

#include <vector> 
#include "wrappers.h" 

class Hits { 

    public: 
     Hits(); 
     std::vector<word_idx_value> getVector() {return speech_hits;} 
     const std::vector<word_idx_value> getVector() const {return speech_hits;} 
     void add(const word_idx_value&); 
     Hits &operator+=(const Hits&); 
    private: 
     std::vector<word_idx_value> speech_hits; 
}; 

#endif 
+0

Können wir Ihre Mitgliedsfunktion getVector() sehen? Vielleicht verändert es da etwas? – rlbond

+1

Was gibt return getVector() zurück? Ist es eine Kopie eines Vektors oder ein Verweis auf einen vorhandenen Vektor, der irgendwo anders gespeichert ist? – Wacek

+0

Ich habe es geändert, um durch Referenz und nicht nach Wert zurückzukehren. Es scheint in Ordnung zu sein, aber warum würde der Wert so sehr auf das Ergebnis wirken? –

Antwort

9
for(vector<random>::iterator it = foo.getVector().begin(); 

Der temporäre Vektor zurückgegeben, wenn Sie foo.getVector() tun und es wird zerstört der Moment ; angetroffen wird nach foo.getVector().begin(); Daher Iterator innerhalb der Schleife ungültig wird.

Wenn Sie den Wert foo.getVector(); in Vektor v (v = foo.getVector();) speichern und dann den Vektor v verwenden, funktioniert es gut. Dies liegt daran, dass der Vektor v während der Schleife gültig ist.

+0

Das stimmt. Aber beachten Sie, dass sogar etwas wie std :: copy (foo.getVector(). Begin(), foo.getVector(). End(), dest) ein undefiniertes Verhalten hat (wie in meiner Antwort), obwohl beide temporäre Vektoren bis leben std :: copy gibt zurück. –

+0

Ja. Wie Sie erwähnt haben, sind es zwei Kopien von Vektor und Iteratoren sind unterschiedlich. –

7

getVector() gibt einen Vektor von Wert. Die beiden Aufrufe von getVector (begin() und end()) geben verschiedene Kopien des Vektors zurück, sodass Sie begin() für ein Objekt und end() für ein anderes Objekt aufrufen. Sie erhalten zwei Iteratoren in zwei verschiedene Container. Der Vergleich dieser beiden Iteratoren mit! = Ergibt einen undefinierten Wert.

2

getVector() gibt Vektor nach Wert zurück und im ersten Fall erhalten Sie eine temporäre Variable, die zerstört wird, sobald Sie sich in der Schleife befinden. Im zweiten Fall kopieren Sie das Ergebnis in eine lokale Variable, die innerhalb der Schleife noch aktiv ist. Eine mögliche Lösung besteht darin, den Vektor durch const-Referenz zurückzugeben.

0

die getVector Funktion modifizieren, um die Objektreferenz wie diese zurückzubringen: std :: vector <word_idx_value> & getVector() {return speech_hits;}

1

Sie Fehler in der getVector() Methode. Rückgabe per Referenz.

Wenn Sie nicht per Referenz zurückgeben, erstellen Sie eine temporäre Kopie. Die Kopie wird dann zerstört, nachdem sie verwendet wurde. In diesem Fall wird nach Ausführung von begin() das temporäre Objekt zerstört, und somit ist der von begin() zurückgegebene Iterator ungültig.

Verwandte Themen