C ++遍历扩展容器 [英] C++ Iterate through an expanding container

查看:65
本文介绍了C ++遍历扩展容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在遍历一个容器的同时扩展它,会遇到新的元素还是旧的元素,将会发生什么

What will happen if I expand a container while iterating through it, may I meet the new elements or just the old ones

std::vector<int> arr(0);
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);

for (auto& ele : arr) {
    if (4 == ele) std::cout << "meet new eles" << endl;
    arr.push_back(4);
}


推荐答案

push_back 可能会使向量的任何迭代器失效,而您所拥有的行为是不确定的。

push_back may invalidate any iterator to the vector, what you have there is undefined behaviour.

std :: vector 内部分配一个数组,其元素连续存储在内存中。为此,它需要预先分配可能需要的大小的估算值,即向量的容量。在 push_back ,如果达到容量,它将分配一个更大的新数组,将先前数组的所有内容复制/移动到新数组,然后删除旧数组。

std::vector internally allocates an array with its elements stored contiguously in memory. To do so it needs to preallocate an estimate of the size it may need, that's known as the capacity of the vector. At push_back if the capacity is reached it allocates a new bigger array, copies/moves all the contents of the previous array to the new one and then deletes the old one. That invalidates the iterators, that keep pointing to a deleted array.

还值得一提的是,分配新数组会大大提高性能。如果知道向量的大小,请始终使用 reserve () 来预分配内存。

Also worth mentioning that the allocation of the new array adds a considerable performance hit. If you know the size that your vector will have always use reserve() to preallocate memory.

现在,正确的是,如果您在手之前预留了容量,而决不退缩超过该容量迭代器将不会失效(仅是过去的迭代器),并且由于它们指向连续元素数组,因此您可以不断对其进行递增。但是我不建议这样做,因为IMO错误地重新分配矢量的风险不值得。

Now, true is that if you reserve capacity before hand and never push back exceeding that capacity the iterators won't be invalidated (only the past-end iterator) and you can keep incrementing them since they point to an array of contiguous elements. But I wouldn't advice to do so, IMO the risk of reallocating the vector by mistake is not worth it.

这篇关于C ++遍历扩展容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆