尝试实现 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 迭代器快得多?