尝试实现 STL 迭代器时出错

Posted

技术标签:

【中文标题】尝试实现 STL 迭代器时出错【英文标题】:Error trying to implement STL iterators 【发布时间】:2017-05-05 22:10:40 【问题描述】:

我对 STL 和迭代器相当陌生。我经常使用它们,但现在才了解它们的真正工作原理。对于一项任务,我的任务是重写一些 STL 迭代器以了解幕后发生的事情。我正在通过我的insert_iterator

template <class Container>
class m_insert_iterator : public std::iterator<output_iterator_tag, void, 
void, void, void>

protected:
    Container* container;
    typename Container::iterator it;

public:
    typedef Container container_type;

    // Constructor:
    m_insert_iterator(Container &x, typename Container::iterator i)
    
        *container = x;
        it = i;
    

    // Assignment operator:
    m_insert_iterator<Container> &operator=(const typename Container::value_type &value)
    
        it = container->insert(this, value);
        ++it;
        return *this;
    

    // No-ops:
    m_insert_iterator<Container> &operator*()  return *this ;
    m_insert_iterator<Container> &operator++()  return *this ;
    m_insert_iterator<Container> &operator++(int)  return *this ;
;

int main()

    vector<int> v 2, 3, 4 ;
    m_insert_iterator<vector<int>> ins_it(v, v.begin());
    ins_it = 1;

    for (int i = 0; i < v.size(); i++)
    
         cout << v[i] << " ";
    

    system("pause");

每当我调用构造函数时,我的程序都会在*container = x 上崩溃。在调试器中,我收到一条错误消息,内容为“0xC0000005:访问冲突读取位置 0x00000000。”为什么会这样?

【问题讨论】:

【参考方案1】:

您的错误在于您对指针的理解,您不能为未初始化的指针分配任何内容。所以你不能在构造函数中分配对未初始化指针的引用:

*container = x;  // container is uninitialized, so this function will generate an AccessViolation

你应该把它当作

container = std::addressof(x);

在这种情况下,您使用传递给您的引用的地址初始化您的指针,但在您的情况下,您试图将引用复制到指针指向它的地址,并且由于您的指针未初始化,因此您是试图写入内存的未知位置。

在最好的情况下,你会得到一个 AccessDenied 或类似的东西,但如果它碰巧写入你的程序可写的内存,你也会导致奇怪的错误。例如,您可以覆盖一个或多个变量的值

【讨论】:

谢谢!我意识到我一发布就犯了那个愚蠢的错误,而且我不再遇到那种崩溃了。我现在将成员声明为Container* container = new Container;,据我所知,它有效。现在,当我调用operator= 时,我遇到了一个崩溃,说明“表达式:向量插入迭代器超出范围”。对此有点困惑,因为m_insert_iterator.it 应该将迭代器存储到v 的开头,对吗? (我已经更新了问题以包含一个测试程序。) new Container 创建了一个新容器,这样复制的迭代器就不会指向您所指向的容器。 BigBoss说怎么办:container = std::addressof(x); 谢谢你们,它的工作。看来我需要后退几步,再好好看看指针。

以上是关于尝试实现 STL 迭代器时出错的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用指针的 STL 算法比 std::vector 迭代器快得多?

STL之traits编程技法

STL迭代器之向量

STL源码剖析——iterators与trait编程#2 Traits编程技法

使用refs实现迭代器时的生命周期推断问题

STL迭代器相关的输出迭代器