【问题标题】:In C++ standard, Why Infinite loop occurs when i use list.begin() as list.splice()'s first and third parameters at the same time在 C++ 标准中,当我同时使用 list.begin() 作为 list.splice() 的第一个和第三个参数时,为什么会发生无限循环
【发布时间】:2017-05-01 21:35:54
【问题描述】:

当我同时使用 begin() 作为 list.splice() 的第一个和第三个参数时, 我不知道为什么输出有无限循环。

#include <list>
#include <iostream>
#include <iterator>
using namespace std;

int main() {
    list<int> mylist;
    for (int i = 1; i < 10; i++)
        mylist.push_back(i);
    mylist.splice(mylist.begin(), mylist, mylist.begin(), mylist.end());

    for (auto it = mylist.begin(); it != mylist.end(); it++) {
        cout << *it << " ";
    }
}

【问题讨论】:

  • 你用的是什么编译器? VS 2015 不会永远循环。
  • "Data races Both the container and x are modified. Concurrently accessing or modifying their elements is safe, although iterating x or ranges that include position is not." 您正在迭代一个包含position 的范围。此外,“这有效地将这些元素插入到容器中并将它们从 x 中删除,从而改变了两个容器的大小”(同一来源),那么您到底希望在那里发生什么? myList(参数一)在此调用后应该为空。
  • @grek40 我同意将列表拼接到自身的整个想法是愚蠢的并且不应该工作,但我找不到任何关于这里应该发生什么的参考。如果只有 1 个线程,如何并发访问?
  • @Ap31 第二部分是重要的部分:“虽然迭代 x 或包含位置的范围不是”。通过为第一个和第三个参数提供相同的迭代器,这是违反的,因为很可能第三个参数将用于迭代。
  • @grek40 这部分似乎是关于并发访问,而不是关于方法使用。它似乎暗示的是“您可以通过list::splice 调用同时修改来自另一个线程的元素,但您不能迭代” - 有意义,但与这个特定问题无关

标签: c++ list splice


【解决方案1】:

代码表现出未定义的行为:

异常安全

(...) if (...) position is in the range [first,last) in (3), it causes undefined behavior.

这并不能完全解释为什么会发生无限循环,但它解释了为什么无限循环是一种可能的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-14
    • 2019-10-10
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 2011-12-08
    相关资源
    最近更新 更多