【问题标题】:Iterator lifetime迭代器生命周期
【发布时间】:2020-07-26 11:30:08
【问题描述】:

原来是这样的:

vector <string>::iterator * it;
{
    vector <string> v{"asd", "asd"};
    auto iter = v.begin();
    it = new vector <string>::iterator(iter);
}
(**it) = string("asd");

现在,我在网上找不到任何资源来告诉我这是 UB 还是有效代码。

我的问题是:
当我创建一个迭代器时,如果该迭代器的生命周期比引用的容器长,是未定义的行为还是在标准中的某个地方定义?

【问题讨论】:

  • 为什么要动态创建迭代器?为什么要为已经消失的向量的向量元素分配一些东西?
  • 我无法参考标准来支持这一点,但对我来说很明显,如果你使用迭代器,它将是 UB,但如果它只是存在,你就可以了。跨度>
  • 我不想这样做,但我正在构建一个类似于 vector 的容器,我想知道我是否必须管理这种情况,或者 STL 中是否也是 UB @idclev463035818
  • 好的,不是说这个问题是无意义的,只是代码;)。有趣的是,即使是这个详尽的答案似乎也没有提到那个案例:stackoverflow.com/questions/6438086/iterator-invalidation-rules
  • @john 谢谢,但是如果我运行这段代码,运行时没有错误,并且 clang 不会产生任何警告......

标签: c++ vector iterator lifetime


【解决方案1】:

在您发布的代码中,

(**it) = string("asd");

导致未定义的行为。

*iter 是一个迭代器,但当您到达该行时,对应的 vector 已不存在。因此,**iter 类似于取消引用悬空指针。顺便说一句,如果您只使用 iterator 而不是 iterator*,这不会改变。

以下代码也会导致未定义的行为。

vector <string>::iterator it;
{
    vector <string> v{"asd", "asd"};
    auto iter = v.begin();
    it = iter;
}
(*it) = string("asd");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    相关资源
    最近更新 更多