C ++: первый элемент вектора "развращения" - PullRequest
3 голосов
/ 13 мая 2009

У меня есть класс (foo), который содержит вектор.

Если я попробую перебрать элементы в векторе, вот так:

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; за пределами цикла, но, похоже, работает нормально. </p>

Спасибо.

Edit:

Вот мой заголовочный файл:

#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

Ответы [ 5 ]

9 голосов
/ 13 мая 2009
for(vector<random>::iterator it = foo.getVector().begin();

Временный вектор возвращается, когда вы делаете foo.getVector(), и он уничтожается в момент, когда ; встречается после foo.getVector().begin(); Следовательно, итератор становится недействительным внутри цикла.

Если вы сохраняете значение foo.getVector(); в векторе v (v = foo.getVector();), а затем используете вектор v, он работает нормально. Это потому, что вектор v действителен во всем цикле.

7 голосов
/ 13 мая 2009

getVector () возвращает вектор по значению. Два вызова getVector (begin () и end ()) возвращают разные копии вектора, поэтому вы вызываете begin () для одного объекта и end () для другого. Вы получите два итератора в два разных контейнера. Сравнение этих двух итераторов с! = Дает неопределенное значение.

2 голосов
/ 13 мая 2009

getVector () возвращает вектор по значению, и в первом случае вы получаете временную переменную, которая уничтожается, когда вы находитесь внутри цикла. Во втором случае вы копируете результат в локальную переменную, которая все еще жива в цикле. Возможное решение - вернуть вектор по константной ссылке.

1 голос
/ 13 мая 2009

Ваша ошибка в методе 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 (), недопустим.

0 голосов
/ 13 мая 2009

измените функцию getVector, чтобы она возвращала ссылку на объект следующим образом: std :: vector & getVector () {return speech_hits;}

...