C++ for-each 语句触发 "vector iterators incompatible"断言失败 : this->_Getcont() == 0

标签 c++ c++11 vector stl

这是与 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];
}

我根本没有在循环体中修改 vector ,事实上,断言发生在第一次迭代之前。该 vector 在调试器中看起来是正确的,但我对 STL 的了解还不够,无法查找损坏。在 STL 内部,断言失败来自:

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() 为 NULL,因为(_Myproxy_Iterator_base12 中为 NULL)。 调用堆栈是:

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)
    ...

我怀疑设置 vector 的代码以某种方式搞砸了,但我不确定。我也很难编写一个更简单的复制器,但程序应该是完全确定的(单线程,而不是随机变量,总是断言)。

此外,我之前还遇到了一个不同的类似断言失败 "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(其实是同一个vector)。

我提到这个是因为在 STL 中,此失败的条件最终也是 this->_Getcont() == 0,我怀疑它们是相关的。 _Getcont()Vector_const_iterator 中为 0 是什么意思?

vector 从容器中出来

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> &)

最佳答案

终于找到问题了。 vector 设置代码中的一条路径正在破坏 vector 的状态(将其设置为 0 作为更大内存块的一部分)。这不会对 vector 中的前三个字段造成损害:_Myfirst_Mylast_Myend,因为这些字段在初始 vector 中为 0。此外,数组索引运算符和 push_back 等其他方法等大多数功能仍然正常运行。但是,第四个字段 _Myproxy 最初是非零的,清除它会禁用基于迭代器的功能。因此,for-each 循环、vector::back() 和其他循环都因不同的假错误而失败,例如错误的边界检查、错误的不兼容迭代器等...

关于C++ for-each 语句触发 "vector iterators incompatible"断言失败 : this->_Getcont() == 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21923800/

相关文章:

c++11 - 如何添加 -std=c++11 来制作文件

c++ - 为什么此代码无法将 char 推回到 vector <char> 中?

r - 用 R 在向量中思考

c++ - 此类代码中 gcc 和 clang 之间的不同行为

c++ - 在具有静态对象的类的析构函数中使用 exit(),不会像预期的那样进入无限循环

c++11 - x86-SSE指令是否具有自动发布获取指令?

c++ - 为什么字符串的行为在这里不同?为什么第一个 for 循环不打印任何内容而第二个 for 循环正确打印输出

c++ - 如何在 Windows 上为调用用户获取桌面的绝对路径

c++ - std::vector 混合数据类型

c++ - 当包含 GLAD 时,glClear() 会使 GLFW 崩溃