我在将初始化的迭代器分配给未初始化时遇到问题。使用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 ++吗?
我需要这段代码来实现一个“游标”类,它既可以指向任何地方,也可以指向列表中的特定元素。如果我没有对容器的引用,我还可以将其用作未初始化迭代器的值?
答案 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变量也会导致未定义的行为。