C++ 向量迭代器不兼容
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8421623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Vector Iterators Incompatible
提问by IG83
I have a class with a std::vector data member e.g.
我有一个带有 std::vector 数据成员的类,例如
class foo{
public:
const std::vector<int> getVec(){return myVec;} //other stuff omitted
private:
std::vector<int> myVec;
};
Now at some part of my main code I am trying to iterate through the vector like this:
现在在我的主要代码的某些部分,我试图像这样遍历向量:
std::vector<int>::const_iterator i = myFoo.getVec().begin();
while( i != myFoo.getVec().end())
{
//do stuff
++i;
}
The moment I reach this loop, I get the aforementioned error.
当我到达这个循环时,我得到了上述错误。
回答by FailedDev
The reason you are getting this, is that the iterators are from two (or more) different copies of myVec. You are returning a copy of the vector with each call to myFoo.getVec()
. So the iterators are incompatible.
你得到这个的原因是迭代器来自 myVec 的两个(或更多)不同的副本。每次调用 时,您都会返回向量的副本myFoo.getVec()
。所以迭代器是不兼容的。
Some solutions:
一些解决方案:
Return a const reference to the std::vector<int>
:
返回对 的 const 引用std::vector<int>
:
const std::vector<int> & getVec(){return myVec;} //other stuff omitted
Another solution, probably preferable would be to get a local copy of the vector and use this to get your iterators:
另一个解决方案,可能更可取的是获取向量的本地副本并使用它来获取迭代器:
const std::vector<int> myCopy = myFoo.getVec();
std::vector<int>::const_iterator i = myCopy.begin();
while(i != myCopy.end())
{
//do stuff
++i;
}
Also +1 for not using namespace std;
也 +1 表示不 using namespace std;
回答by Adrian Cornish
You are returning a copy of the vector. Because you are returning by value - your call to begin() and end() are for completely different vectors. You need to return a const & to it.
您正在返回向量的副本。因为您是按值返回 - 您对 begin() 和 end() 的调用是针对完全不同的向量。你需要返回一个 const & 给它。
const std::vector<int> &getVec(){return myVec;}
I would do this slightly differently though. I'd make the class act a little like a standard container
不过,我的做法略有不同。我会让班级表现得有点像标准容器
class Data
{
public:
typedef std::vector<int>::const_iterator const_iterator;
const_iterator begin() const { return myVec.begin(); }
const_iterator end() const { return myVec.end(); }
};
Data::const_iterator i=myFoo.begin();
while(i != myFoo.end())
{
//
}
回答by nmr
Another cause of the MSVC STL debug assertion "vector iterators incompatible" is operating on an invalidated iterator.
MSVC STL 调试断言“向量迭代器不兼容”的另一个原因是在无效迭代器上运行。
I.e. v.erase(i)
, and then compare i != v.end()
the erase invalidates i
and so it cannot be used in a comparison.
即v.erase(i)
,然后比较i != v.end()
擦除无效i
,因此不能用于比较。
回答by jdehaan
The problem is that you always return another copy of the vector. Use a reference:
问题是你总是返回向量的另一个副本。使用参考:
const std::vector<int>& getVec(){return myVec;} //other stuff omitted
回答by zinking
well, I don't think vector copy could be the only cause, that seems to be too obivious to me.
好吧,我不认为矢量副本可能是唯一的原因,这对我来说似乎太明显了。
in my case I just find that corrupted stack, heap, uninteneded changes could also result in this failure, and it will in fact hiding the underlying reason. in my case, I changed to use indexer to iterate through and find the root cause.
就我而言,我只是发现损坏的堆栈、堆、意外更改也可能导致此失败,并且实际上会隐藏根本原因。就我而言,我改为使用索引器进行迭代并找到根本原因。
回答by kalmiya
Another reason why this assert can trigger is if you would allocate "foo" with 'malloc' instead of 'new', effectively skipping the constructor(s).
此断言可以触发的另一个原因是,如果您将使用 'malloc' 而不是 'new' 分配“foo”,从而有效地跳过构造函数。
It's unlikely to happen to a project developed from scratch in C++, but when converting plain-C code to C++ (replacing a static array[] in some struct with an stl-vector) you might just not realise that dynamic instances of said struct (and the members inside) are not going to have their constructor called - unless you also change 'malloc' to 'new'.
用 C++ 从头开始开发的项目不太可能发生这种情况,但是当将纯 C 代码转换为 C++(用 stl 向量替换某些结构中的静态数组 [])时,您可能只是没有意识到所述结构的动态实例(和里面的成员) 不会调用他们的构造函数 - 除非你也将 'malloc' 更改为 'new'。
回答by Rob K
You are making a constant copy of the member vector, not accessing the member vector.
您正在制作成员向量的常量副本,而不是访问成员向量。
Change this:
改变这个:
const std::vector<int> getVec(){return myVec;} //other stuff omitted
to this:
对此:
const std::vector<int> & getVec(){return myVec;} //other stuff omitted
To go a little deeper, the iterator you get from this statement:
更深入一点,你从这个语句中得到的迭代器:
std::vector<int>::const_iterator i = myFoo.getVec().begin();
is an iterator to the temporary copy of your vector, which goes away after that statement executes, invalidating the iterator.
是向量临时副本的迭代器,该副本在该语句执行后消失,使迭代器无效。
回答by Igor Oks
Change
改变
const std::vector<int> getVec(){return myVec;}
to
到
const std::vector<int>& getVec(){return myVec;}
回答by Drew Hall
Your getVec() function returns a deep copy of the member vector, so the two getVec() calls you make to retrieve iterators get iterators to different containers. That is, you can't reach getVec().end() from a separate getVec().begin() iterator without invoking undefined behavior.
您的 getVec() 函数返回成员向量的深层副本,因此您为检索迭代器而进行的两次 getVec() 调用将迭代器获取到不同的容器。也就是说,您无法在不调用未定义行为的情况下从单独的 getVec().begin() 迭代器访问 getVec().end()。
You can solve this in two ways:
您可以通过两种方式解决此问题:
1) Have getVec return a const reference (that is, const std::vector&) (preferred) or...
1) 让 getVec 返回一个 const 引用(即 const std::vector&)(首选)或...
2) Replace the two getVec() calls with one and save the result to a std::vector variable. Then, use that variable for both calls to begin() and end(). E.g:
2) 用一个替换两个 getVec() 调用并将结果保存到 std::vector 变量。然后,在调用 begin() 和 end() 时使用该变量。例如:
std::vector<int> v = myFoo.getVec();
std::vector<int>::const_iterator b = v.begin();
std::vector<int>::const_iterator e = v.end();
回答by u6318454
Because you are returning by value - your call to begin() and end() are for completely different vectors. You need to return a const & to it
因为您是按值返回 - 您对 begin() 和 end() 的调用是针对完全不同的向量。你需要返回一个 const & 给它