【问题标题】:"Expression: list iterators incompatible" happening randomly during iteration through a list“表达式:列表迭代器不兼容”在迭代列表期间随机发生
【发布时间】:2015-03-01 14:36:34
【问题描述】:

我一直在尝试使用 std::list,但是我的工作被以下错误破坏了:

Debug Assertion Failed!

Program: C:\Windows\system32\MSVCP120D.dll
File: c:\program files (x86)\microsoft visual studio 12.0\vc\include\list
Line: 289

Expression: list iterators incompatible

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)

我已经搜索了一些(实际上是几个小时),但没有解决我的问题。 错误显示在以下函数中:

void Plane::createFrame(){
    for( int i = 0; i < 400; i++ ){
        frame[i] = '_';
    }
    for (std::list<Unit>::iterator iterator = units_container.begin();
        iterator != units_container.end(); ++iterator) {

        iterator->draw(frame, 20);
    }
}

draw 函数如下所示:

void Unit::draw( char(&world)[400], int width ){
    world[ position ] = avatar;     
}

另一个有趣的事情是我设法“控制”了这个错误:

void Plane::createFrame(){
    for( int i = 0; i < 400; i++ ){
        frame[i] = '_';
    }
    for (std::list<Unit>::iterator iterator = units_container.begin();
        iterator != units_container.end(); ++iterator) {

        if( iterator->getPosition() < 0 ||
            iterator->getPosition() > 399 ){
            break;
        }
        iterator->draw(frame, 20);
    }
}

更改后的createFrame() 似乎不受先前错误的影响。

如果我更改我的代码,我会在不同的地方发生相同的错误(不过,更改是必要的。现在总是createFrame() 显示错误)。它总是显示在几乎相同的for 中,可能调用了不同的函数。

createFrame() 正在循环中调用。错误通常发生在 100 圈之后。更改了createFrame() 随机使用break;,但从未出现错误。

没有其他线程可以访问列表。

我正在使用erase(),但似乎与错误没有任何关联。

我希望我没有错过任何明显的事情,但现在我不能确定。 感谢您的宝贵时间。

【问题讨论】:

  • 看起来您正在越界写入 world 数组。您添加的检查可以防止这种情况发生。但是,如果您自己修复了错误,那么您的问题是什么?
  • 一个完整的例子会有所帮助。我认为在您的代码中的某处,您尝试使用来自两个不同列表对象的迭代器。
  • @interjay 我已经解决了效果,但我不知道根本原因。这就是困扰我的地方。对不起,我没有说得更清楚。似乎最黑暗的地方在灯下。虽然它并没有解决我所有的担忧。但现在我必须做一些检查才能得出更多结论。

标签: c++ list iterator std


【解决方案1】:

您有一个作为char(&amp;world)[400] 传递给Unit::draw 的数组,并且您正在写入该数组的索引position

如果position 不在 0 和 399 之间,这将导致未定义的行为。这可能会导致各种症状:您的代码可能会崩溃、可能无法正常工作,或者可能会显示看似无关的错误消息,例如您收到的关于迭代器的错误消息。

当您添加检查 position 是否介于 0 和 399 之间时,此处不再发生错误。你说它现在发生在其他地方,所以你应该检查那里是否有任何越界数组访问(或任何其他类型的未定义行为)。最好首先确保position 不会被分配无效值。

【讨论】:

  • 我已经检查过了,它似乎是正确的(45 000 圈)。这是一个相当尴尬的错误,我现在觉得很愚蠢。有一种可能会传递错误的参数,因为我忘记在“if (new_position > map_size - 1)”中添加“-1”。事实上,在我的代码中距离很远并没有帮助。调试器消息似乎有点奇怪。无论如何,非常感谢你,这非常有帮助。
猜你喜欢
  • 1970-01-01
  • 2013-06-10
  • 2020-11-02
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多