2009-05-13 13 views
3

私はベクトルを含むクラス(foo)を持っています。C++:ベクトル "corrupting"の最初の要素

私はそうのようなベクトルの要素を反復処理しようとした場合:

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

} 

最初の要素は常に破損していると、ゴミデータを返します。

行う場合は、何かのように:

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

} 

すべてが正常に動作しているように見えます。私が知らない「落ち穴」はありますか?

私はまた、Coutをやってみました。< < foo.getVector()[0] < < endl;ループの外側にあるが、それはうまく動作しているようだ。

ありがとうございました。

編集:

ここに私のヘッダファイルです:

#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

getVector()メンバー関数が見えますか?多分何かそれを修正するでしょうか? – rlbond

+1

getVector()は何を返しますか?それはベクターのコピーか、他の場所に保存されている既存のベクターへの参照ですか? – Wacek

+0

私は値ではなく参照で返すように変更しました。それは正常に動作しているようですが、なぜ値渡しが結果に大きな影響を与えるのでしょうか? –

答えて

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

一時的なベクトルが返され、それがfoo.getVector().begin();したがってイテレータはループ内で無効になった後に瞬間;が発生した破壊されます。

foo.getVector();の値をベクトルv(v = foo.getVector();)に格納し、ベクトルvを使用すると正常に動作します。これは、ベクトルvがループ全体で有効であるためです。

+0

これは正しいです。しかし、両方の一時的なベクトルが生きているにもかかわらず、std :: copy(foo.getVector()。begin()、foo.getVector()。end()、dest)のようなものでさえ未定義の振る舞いをしています。 std :: copyが返されます。 –

+0

はい。あなたが言及したように、それはベクトルの2つのコピーであり、イテレータは異なります。 –

7

それぞれgetVectorは()の値によってベクトルを返します。 getVector(begin()とend())の2回の呼び出しはベクトルの異なるコピーを返します。したがって、あるオブジェクトではbegin()を呼び出し、別のオブジェクトではend()を呼び出します。あなたが得るのは、2つの異なるコンテナへの2つのイテレータです。これらの2つのイテレータを!=と比較すると、未定義の値が得られます。あなたがfoo.getVector()を行う際

2

getVector()はベクトルを値で返します。最初のケースでは、ループ内にあると一時的な変数が破棄されます。 2番目のケースでは、ループ内でまだ生きているローカル変数に結果をコピーします。可能な解決策は、const参照によってベクトルを返すことです。

0

このようなオブジェクト参照を返すために、それぞれgetVector関数を変更: のstd ::ベクトル<word_idx_value> &それぞれgetVectorは(){speech_hitsを返す;}

1

あなたエラーがそれぞれgetVector()メソッドです。 ご返却ください。

class Hits 
{ 
    public: 
    std::vector<word_idx_value>& getVector() {return speech_hits;} 
    //      ^
    //      Add the & to return by reference. 

    // You may also want a const version at some point. 
    std::vector<word_idx_value> const& getVector() const {return speech_hits;} 

一時的なコピーを作成しています。コピーは、使用後に破棄されます。この場合、begin()の実行後に一時オブジェクトが破棄され、begin()によって返されたイテレータは無効です。

関連する問題