为什么解除引用迭代器会使输出流被删除?

时间:2016-06-28 17:50:19

标签: c++ iterator cout deque

我练习std::deque,特别是迭代器

我测试了end迭代器。像这样:

    std::deque<const char*> wup {"how","are","you","doing","today?"};
    std::deque<const char*>::iterator it = wup.end();

然后,我想打印it我知道结束迭代器是空的。

enter image description here

然后我尝试使用2个cout语句打印it的内容:其中一个在--it之前,另一个在--it之后

但如果我在cout之前写--it,则最后cout不会出现在输出中。

这样的事情:

std::deque<const char*> wup {"how","are","you","doing","today?"};
std::deque<const char*>::iterator it = wup.end();
std::cout<<"Before --it: "<<*it<<std::endl;// okay, it works good | and finishes console
--it;
std::cout<<"After --it: "<<*it<<std::endl;// I do not know why it does not appear.

输出:

    Before --it:
    Process returned 0 (0x0)   execution time : 0.010 s
    Press ENTER to continue.

我在哪里弄错了?
如果取消引用迭代器是错误的...
为什么会出现这种情况,毫无例外地削减输出流
非常感谢。 测试:
OS: Ubuntu 16.01
compiler: g++ version: 5.3.1
IDE: code::blocks 16.01

编辑: 我在/reference/en/cpp/container/map/erase.html中找到了 note

迭代器pos必须有效且可解除引用。因此,end()迭代器(有效但不是 dereferencable )不能用作pos的值。

  

我认为这是真正的原因,为什么......。

我的母语不是英语,所以请原谅我,如果你看到一些错误

1 个答案:

答案 0 :(得分:2)

  

我在哪里弄错了?

这一行:

std::cout<<"Before --it: "<<*it<<std::endl;

取消引用一个指向容器末尾的迭代器,该迭代器是未定义的行为。

  

为什么会这样,在没有任何异常的情况下切断输出流?

这个问题分为两部分:

  1. 为什么会切断输出流?因为未定义的行为未定义。你不知道会发生什么。有很多关于此的信息:http://en.cppreference.com/w/cpp/language/ub

  2. 为什么没有例外?为了给可能导致UB的所有内容提供例外,c++必须检查每个去引用,这对于非常小的增益而言在计算上是昂贵的。用户可以正确使用迭代器接口。在以下示例中也是如此:

  3.  int a[5];
     a[6] = 10; // Why does c++ allow this when it is clearly a mistake? Because the user is 
                // responsible for writing good code, not the compiler, and certainly
                // not the run-time exception handler.