std :: vector несовместимый итератор - PullRequest
1 голос
/ 22 октября 2010

У меня есть ошибка (несовместимые векторные итераторы) во время выполнения в моей C ++ программе, которую я не понимаю [(Windows / Visual C ++ 2008 Express)]

Вот упрощенная версия моей проблемы:

#include <vector>

class A
{
    int mySuperInt;
public:
    A(int val) : mySuperInt(val) {}
};
class B
{
    std::vector<A*> myAs;
    public:
        B() 
        {
            myAs.push_back(new A(1));
        };
        const std::vector<A*> getA() const {return myAs;}
};

int main()
{
    std::vector<B>* myBs = new std::vector<B>;

    myBs->push_back(B());

    std::vector<B>::const_iterator it_B = myBs->begin();
    for ( ; it_B != myBs->end(); ++it_B)
    {
        std::vector<A*>::const_iterator it_A = it_B->getA().begin();
        for ( ; it_A != it_B->getA().end(); ++it_A) // <-- Error during execution: vector iterator incompatibles
        {
            // Do stuff
            // ...
        }
    }
}

Я что-то пропустил?

Заранее спасибо за ваши ответы.

Ответы [ 3 ]

6 голосов
/ 22 октября 2010

Ваша функция getA() возвращает вектор по значению.Вы инициализируете свой итератор цикла в начале этого вектора, но так как возвращаемый вектор является временным, он уничтожается в конце этой строки.

// at the end of this line the vector returned by getA is gone, so it_A is invalid.
std::vector<A*>::const_iterator it_A = it_B->getA().begin();

Поэтому итератор больше не действителен.Вместо этого вы должны вернуть ссылку на вектор следующим образом (обратите внимание на &):

const std::vector<A*> & getA() const {return myAs;}
1 голос
/ 22 октября 2010

Спасибо за полное и простое воспроизведение.Проблема здесь в том, что вы используете итераторы из двух разных векторов, это проверка отладки во время выполнения.

Вы, вероятно, не собирались это делать, но это результат возвращаемого типа getA.

Вы возвращаете копию вектора, и вы, вероятно, хотели вернуть ссылку на вектор, например так:

const std::vector<A*>& getA() const {return myAs;}

1 голос
/ 22 октября 2010

Вы понимаете, что B :: getAs () возвращает копию своего myAs.Таким образом, вектор, на который проходит it_A, - это копия, отличная от того, с которым getA (). End () он сравнивается ... То есть цикл for никогда не останавливается.(Хуже того, it_A располагается над вектором <>, который является временным, поэтому он уничтожается, и всякое случайное дерьмо может быть записано в это хранилище, пока вы притворяетесь, что итерируете его.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...