C ++ for-each语句触发“向量迭代器不兼容”断言失败:this-> _Getcont()== 0 [英] C++ for-each statement triggers "vector iterators incompatible" assertion failure: this->_Getcont() == 0
问题描述
这是使用Visual Studio 2012.
This is with Visual Studio 2012.
static void func(
...,
const std::vector<std::string> &opt_extra_args_strs,
...)
{
// THIS ASSERTS: "vector iterators incompatible"
for (const std::string &arg_str : opt_extra_args_strs) {
... body does not modify opt_extra_args_strs
// BUT THIS WORKS:
for (size_t a_ix = 0; a_ix < opt_extra_args_strs.size(); a_ix++) {
const std::string &arg_str = opt_extra_args_strs[a_ix];
}
我不是在循环体中修改向量,事实上,断言发生在第一次迭代之前。向量看起来在调试器,但我不知道足够STL来寻找腐败。在STL中,断言失败来自:
I am not modifying the vector at all in the loop body, and in fact, the assertion happens before the first iteration. The vector looks right in the debugger, but I don't know enough about STL to look for corruption. Inside the STL the assertion failure comes from:
void _Compat(const _Myiter& _Right) const {
// test for compatible iterator pair
if (this->_Getcont() == 0 // THIS FAILS (_Getcont() == 0)
...) {
_DEBUG_ERROR("vector iterators incompatible");
与 this-> _Getcont()
因为( _Myproxy
在 _Iterator_base12
中为NULL)。
调用堆栈是:
with this->_Getcont()
being NULL because (_Myproxy
is NULL in the _Iterator_base12
).
The call stack is:
msvcp110d.dll!std::_Debug_message(const wchar_t * message, const wchar_t * file, unsigned int line) Line 15 C++
Main.exe!std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >::_Compat(const std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > & _Right)
Main.exe!std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >::operator==(const std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > & _Right)
Main.exe!std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >::operator!=(const std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > & _Right)
Main.exe!run_test(..., const std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > & opt_extra_args_strs)
...
我怀疑设置向量的代码正在以某种方式调整它,但我不确定。我也很难编写一个更简单的再现器,但程序应该是完全确定性的(单线程,而不是随机变量,总是断言)。
I suspect the code setting up the vector is screwing it up somehow, but I am not sure. I am having difficulty writing a simpler reproducer as well, but the program should be totally deterministic (single threaded, not random variables, always asserts).
此外,我也遇到了一个不同的类似的断言失败向量迭代器+偏移超出范围
(在同一向量上)
Additionally, I also run into a different similar assertion failure earlier "vector iterator + offset out of range"
with the snippet (on the same vector)
template <typename T>
class Elsewhere {
virtual void earlier(
....
std::vector<T> &v) const
{
v.emplace_back(); // empty construction of a T
// T &t = v.back(); // assertion failure
T &val = to[to.size() - 1]; // but this works
... mutates val.
使用 T = std :: string
事实上,同一个向量)。
With T = std::string
(in fact, the same vector).
我提到这一点,因为在STL中,这个失败的条件也是 this-> _Getcont )== 0
,我怀疑他们是相关的。 _Getcont()
在 Vector_const_iterator
中为0意味着什么?
I mention this because within STL the condition for this failure ends up also being this->_Getcont() == 0
, and I suspect them to be related. What does it mean for _Getcont()
to be 0 in a Vector_const_iterator
?
向量来自容器
template <typename T>
struct type {
T m_value;
operator const T &() const {
return value();
}
const T &value() const {
return m_value;
}
};
type<std::vector<std::string>> &t = ... method call that returns ref to it;
... t gets set
func(t); // implicit conversion to (const std::vector<std::string> &)
推荐答案
我终于找到了问题。向量的设置代码中的路径深深地破坏了向量的状态(将其设置为0,作为更大块内存的一部分)。这不会对向量中的前三个字段造成损害: _Myfirst
, _Mylast
和 _Myend
,因为这些字段在初始向量中为0。此外,大多数事情,如数组索引操作符和其他方法,如push_back仍然正确运行。但是,第四个字段 _Myproxy
最初不为零,并清除它禁用基于迭代器的功能。因此,对于每个循环, vector :: back()
,其他所有失败与不同的错误,如伪边界检查,假不兼容的迭代器等...
I finally found the problem. A path deep in the vector's setup code was clobbering the vector's state (memset'ing it to 0's as part of a larger chunk of memory). This caused no harm for the first three fields in vector: _Myfirst
, _Mylast
, and _Myend
since those fields are 0 in an initial vector. Moreover, most things such as the array index operator and other methods such as push_back still functioned correctly. However, the fourth field _Myproxy
was initially non-zero, and clearing it disabled iterator-based functionality. Hence, for-each loop, vector::back()
, and others all fail with different false errors such as false bounds checks, false incompatible iterators, etc...
这篇关于C ++ for-each语句触发“向量迭代器不兼容”断言失败:this-> _Getcont()== 0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!