c++ - std::reverse_iterator 奇怪的行为(UB?)

标签 c++ c++11 iterator

<分区>

我为这个容器创建了一个伪容器类(它不包含任何元素)和一个迭代器类。 以下代码在我的系统上总是输出“776”(我的编译器是 GCC 5.4.0)

#include <iostream>
#include <iterator>

class Container
{
public:
  class Iterator;
  Container()=default;
  Container::Iterator begin();
  Container::Iterator end();
};

class Container::Iterator: public std::iterator<std::bidirectional_iterator_tag, size_t>
{
public:

    Iterator(size_t n);
    size_t& operator*();
    Container::Iterator& operator--();
    const Container::Iterator operator--(int);

    bool operator==(const Container::Iterator& rhs) const;
    bool operator!=(const Container::Iterator& rhs) const;
  private:
    size_t n_;
};



Container::Iterator Container::end()
{
  return Iterator(777);
}





Container::Iterator::Iterator(size_t n):
  n_(n)
{
}

size_t& Container::Iterator::operator *()
{
  return n_;
}

Container::Iterator& Container::Iterator::operator--()
{
  n_--;
  return *this;
}

const Container::Iterator Container::Iterator::operator--(int)
{
  Container::Iterator oldVal = *this;
  n_--;
  return oldVal;
}

int main()
{
 Container cont;
 std::reverse_iterator<Container::Iterator>revit(cont.end());
 //as cppreference says, "For a reverse iterator r constructed from an iterator i, the relationship &*r == &*(i-1) is always true...", so I expect that the output must be the same as if I used instead next commented line, and it does so on my system
  // auto it = cont.end(); it--; std::cout << *it << std::endl;
  std::cout << *revit << std::endl;
 return 0;
}

但是当我使用任何在线编译器(支持 C++11)时,这段代码只输出“0”(除了一个 Clang 版本,然后输出是一些“随机”的大数字)

我想不通,我的错误在哪里?

最佳答案

std::reverse_iterator::operator* is equivalent to

Iterator tmp = current; return *--tmp;

(其中 current 是由这个 reverse_iterator 实例包装的底层迭代器)。

*tmp返回对 tmp 成员的引用- 超出范围并在 std::reverse_iterator::operator* 时被销毁返回,带着那个成员。因此,*revit返回悬空引用;随后尝试使用它会出现未定义的行为。

关于c++ - std::reverse_iterator 奇怪的行为(UB?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47491256/

相关文章:

C++:在包含的头文件中使用#define 常量 (Arduino)

C++ 模板访问具有不同类型的函数

c++ - libstdc++ 中关于 std::list 赋值的错误?

c++ - 如何将反向迭代器与作为代理的迭代器一起使用

C++ static_cast 运行时开销

c++ - 如何将此代码重构为多线程版本?

c++ - 将二维字符串数组与 std::sort 进行比较

java - 获取 Java 的列表迭代器以返回 Object 以外的内容

c++ - 为什么 std::iterator_traits 找不到 value_type?

c++ - 是否可以在 Visual Studio 2013 中设置多个条件断点?