【问题标题】:C++ Keeping track of start iterator while adding itemsC ++在添加项目时跟踪启动迭代器
【发布时间】:2022-01-03 08:50:26
【问题描述】:

我正在尝试在 std::vector 上进行双循环,以探索向量中项目的所有组合。如果结果很好,我将它添加到向量中以进行另一遍。这被用于关联规则问题,但我为这个问题做了一个较小的演示。似乎当我push_back 时,它有时会更改向量,使得原始迭代器不再起作用。例如:

    std::vector<int> nums{1,2,3,4,5};
    auto nextStart = nums.begin();
    while (nextStart != nums.end()){
        auto currentStart = nextStart;
        auto currentEnd = nums.end();
        nextStart = currentEnd;
        for (auto a = currentStart; a!= currentEnd-1; a++){
            for (auto b = currentStart+1; b != currentEnd; b++){
                auto sum = (*a) + (*b);
                if (sum < 10) nums.push_back(sum);
            }
        }
    }

在某些迭代中,currentStart 指向数组外部的位置并提供垃圾数据。是什么导致了这种情况,避免这种情况的最佳方法是什么?我知道修改你迭代的东西是自找麻烦......

【问题讨论】:

  • push_back 使向量上的所有迭代器无效,因为底层内存的重新分配可以移动它。在这种情况下,更安全的方法是使用索引。
  • 改用std::list
  • 只使用索引。它不那么惯用,但对于像这样使迭代器无效的循环来说,这是正确的方法。

标签: c++ iterator


【解决方案1】:
nums.push_back(sum);

如果push_back 最终重新分配向量,push_back 会使向量的所有现有迭代器无效。

这就是矢量的工作原理。最初为向量的增长保留了一些额外的空间。 Vector 保存其内容的内部缓冲区有一些额外的空间可供使用,但是当它已满时,下一次调用 push_back 会为向量的内容分配一个更大的缓冲区,移动现有缓冲区的内容,然后删除现有缓冲区。

所示代码为向量创建和使用迭代器,但任何对 push_back 的调用都会使整个代码无效,并且下一次无效的向量取消引用会导致未定义的行为。

您有两个基本选择:

  1. 当其他值被添加到迭代器时,将向量替换为不会使其现有迭代器无效的其他容器

  2. 使用向量索引而不是迭代器重新实现整个逻辑。

【讨论】:

    猜你喜欢
    • 2018-10-21
    • 2016-04-07
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多