C ++:向量“腐败”的第一个元素

时间:2009-05-13 05:23:54

标签: c++ stl vector iterator cout

我有一个包含矢量的类(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&lt;&lt; foo.getVector()[0]&lt;&lt; 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

5 个答案:

答案 0 :(得分:9)

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

执行foo.getVector()时会返回临时向量,并且在;之后遇到foo.getVector().begin();时它会被销毁。因此迭代器在循环内变得无效。

如果将foo.getVector();的值存储在向量v(v = foo.getVector();)中,然后使用向量v,则可以正常工作。这是因为向量v在整个循环中都是有效的。

答案 1 :(得分:7)

getVector()按值返回向量。 getVector的两次调用(begin()和end())返回向量的不同副本,因此您在一个对象上调用begin()而在另一个对象上调用end()。你得到的是两个不同容器中的两个迭代器。将这两个迭代器与!=进行比较会产生一个未定义的值。

答案 2 :(得分:2)

getVector()按值返回向量,在第一种情况下,您获得一个临时变量,一旦进入循环,它就会被销毁。在第二种情况下,将结果复制到循环内部仍处于活动状态的局部变量中。可能的解决方案是通过const引用返回向量。

答案 3 :(得分: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()返回的迭代器无效。

答案 4 :(得分:0)

修改getVector函数以返回对象引用,如下所示:   的std ::矢量&lt; word_idx_value&GT;&安培; getVector(){return speech_hits;}