循环访问时修改数据结构

| 将元素添加到数据结构(例如向量)时会发生什么情况 遍历它。我不能这样做吗? 我试过了,它坏了:
int main() {
    vector<int> x = { 1, 2, 3 };

    int j = 0;
    for (auto it = x.begin(); it != x.end(); ++it) {
        x.push_back(j);
        j++;
        cout << j << \" .. \";
    }
}
    
已邀请:
某些修改“ 1”的操作会使迭代器无效。 其他容器具有关于迭代器何时生效和无效的各种规则。这是一篇帖子(由您本人真正撰写),其中包含详细信息。 顺便说一下,入口点函数
main()
必须返回
int
int main() { ... }
    
  将元素添加到数据结构(例如向量)并对其进行迭代时,会发生什么情况。我可以不这样做吗? 如果向量自动调整大小,则迭代器将变为无效。因此,只要向量不自行调整大小,您就很安全。 我建议您避免这种情况。 简短说明为何调整大小会使迭代器无效: 最初,向量具有一定的容量(您可以通过调用
vector::capacity()
来知道。),并向其中添加元素,当向量已满时,它将分配更大的内存大小,将元素从旧内存复制到新分配的内存,然后删除旧内存,问题是迭代器仍指向已释放的旧内存。这就是调整大小使迭代器无效的方式。 这是简单的演示。只要看看ѭ6何时变化:
std::vector<int> v;
for(int i = 0 ; i < 100 ; i++ )
{
  std::cout <<\"size = \"<<v.size()<<\", capacity = \"<<v.capacity()<<std::endl;
  v.push_back(i);
}       
部分输出:
size = 0, capacity = 0
size = 1, capacity = 1
size = 2, capacity = 2
size = 3, capacity = 4
size = 4, capacity = 4
size = 5, capacity = 8
size = 6, capacity = 8
size = 7, capacity = 8
size = 8, capacity = 8
size = 9, capacity = 16
size = 10, capacity = 16
在此处查看完整的输出:http://ideone.com/rQfWe 注意:
capacity()
表示向量可以包含的最大元素数量,而不分配新的内存,,10ѭ表示向量当前包含的元素数量。     
一般来说,这是一个坏主意,因为如果调整向量的大小,则迭代器将变得无效(它将指针包装到向量的内存中)。 还不清楚您的代码实际上在试图做什么。如果迭代器没有以某种方式变为无效(假设它被实现为索引),那么我希望您在那里有一个无限循环-永远不会到达终点,因为您总是在添加元素。 假设您要遍历原始元素,并为每个元素添加一个,则一种解决方案是将新元素添加到第二个向量,然后在最后将其连接:
vector<int> temp;

// ...

// Inside loop, do this:
temp.push_back(j);

// ...

// After loop, do this to insert all new elements onto end of x
x.insert(x.end(), temp.begin(), temp.end());
    
这不是一个好主意。 您可以考虑在push_back之后需要调整向量大小的情况。然后需要将其移到更大的内存位置,并且您的迭代器现在将无效。     
虽然以vector为例,但还有其他stl容器可以将元素推回而不会使迭代器无效。将元素推回std :: list不需要对现有元素进行任何重新分配,因为它们不会连续存储(列表而是由通过指向下一个节点的指针链接在一起的节点组成),因此迭代器保持有效它们内部指向的节点仍然驻留在同一地址。     
如果您需要这样做,则可以增加12条最大记录数。这将使向量不再需要调整大小,并且这可以防止崩溃     

要回复问题请先登录注册