分配未初始化的迭代器时发生访问冲突

时间:2011-11-21 15:24:38

标签: c++ visual-studio-2010

我在将初始化的迭代器分配给未初始化时遇到问题。使用Visual Studio 2010构建时,以下代码摘录会产生访问冲突。在以前版本的Visual Studio中,代码应该可以正常工作。

#include <list>

int main() {
    std::list<int> list;
    std::list<int>::iterator it = list.begin();
    std::list<int>::iterator jt;
    it = jt; // crashes in VS 2010
}

这不会被认为是有效的C ++吗?

我需要这段代码来实现一个“游标”类,它既可以指向任何地方,也可以指向列表中的特定元素。如果我没有对容器的引用,我还可以将其用作未初始化迭代器的值?

4 个答案:

答案 0 :(得分:6)

 it = jt; // crashes in VS 2010

这会调用未定义的行为(UB)。根据C ++标准,jt是一个单数迭代器,它与任何容器都没有关联,大多数表达式的结果都是未定义的奇异迭代器。

C ++标准(2003)第24.1 / 5节中的内容(具体见粗体文本),

  

就像指向数组的常规指针一样   保证有一个指针   指向最后一个元素的值   对于任何迭代器类型,数组都是如此   有一个指向的迭代器值   过去的最后一个元素   相应的容器。这些价值观   被称为过去的价值观。值   一个迭代器我的   表达式* i被定义被调用   提领。图书馆永远不会   假设过去的价值是   提领。 迭代器也可以   具有不是的奇异值   与任何容器相关联。   [例子:宣布之后   未初始化的指针x(与int *一样)   x;),x必须始终假定为   指针的奇异值。]   大多数表达的结果是   未定义的奇异值;   唯一的例外是a的赋值   迭代器的非奇异值   具有独特的价值。在这种情况下   奇异值被覆盖了   与任何其他价值相同。   始终是可解除引用的值   奇异的。

如果MSVS2010崩溃了,它是UB的无限可能之一,因为UB意味着任何事情都可能发生;标准没有规定任何行为。

答案 1 :(得分:2)

C ++ 11,24.2.1 / 3:

  

对于奇异值,大多数表达式的结果未定义;该   唯一的例外是破坏一个包含单数的迭代器   value,将非奇异值赋值给迭代器   拥有一个奇异的值,并且,对于满足该值的迭代器   DefaultConstructible要求,使用值初始化迭代器   作为复制或移动操作的来源。

列表是限制性的,您的示例未在允许的例外中列出。 jt是单数且默认初始化的。因此,它不能用作复制操作的来源。

答案 2 :(得分:0)

您需要一个KNOWN值才能使用信号。你没有那个,除非你有一个容器来获取.end(),你认为这是你的问题。

你真正需要做的是远离以为你可以对不涉及容器的古怪案例使用'特殊'迭代器值。迭代器,虽然它们像指针一样工作,但不是指针。它们没有相应的“NULL”。

相反,使用布尔标志值来查看容器是否已设置,并确保在容器变为已知时将迭代器(所有这些,如果有多个)设置为某个有效值,并且丢失容器时,标志会被设置为false。然后,您可以在任何迭代器操作之前检查该标志。

答案 3 :(得分:-1)

list.end()指向容器之外的任何地方,因此我们可以将其视为无处指向。 访问unitialized变量也会导致未定义的行为。