将元素添加到数据结构(例如向量)时会发生什么 迭代它。我可以不这样做吗?
我尝试了这个并打破了:
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 << " .. ";
}
}
答案 0 :(得分:15)
某些修改std::vector
的操作会使迭代器失效。
其他容器有关于迭代器何时失效以及未失效的各种规则。 This is a post(由您真实地)提供详细信息。
顺便说一句,入口点函数main()
必须 返回int
:
int main() { ... }
答案 1 :(得分:11)
在迭代数据结构时将元素添加到数据结构(例如向量)时会发生什么。我不能这个吗?
如果向量调整自身,迭代器将变为无效。只要向量不自行调整大小,你就是安全的。
我建议你避免这种情况。
为什么调整大小会使迭代器失效的简短解释:
最初,向量具有一定的容量(通过调用vector::capacity()
可以知道。),然后向其中添加元素,当它变满时,它会分配更大的内存,复制旧的元素内存到新分配的内存,然后删除旧内存,问题是迭代器仍然指向已经解除分配的旧内存。这就是调整大小使迭代器失效的方法。
这是简单的演示。只需查看capacity
更改时间:
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()
告诉矢量可以包含的最大元素数而不分配新内存,size()
告诉元素数量当前包含的矢量。
答案 2 :(得分:2)
一般来说这是一个坏主意,因为如果向量调整大小,迭代器将变为无效(它将指针包装到向量的内存中)。
还不清楚你的代码究竟在尝试做什么。如果迭代器以某种方式没有变得无效(假设它被实现为索引),我希望你在那里有一个无限循环 - 永远不会达到结束,因为你总是添加元素。
假设你想循环遍历原始的元素,并为每个元素添加一个,一个解决方案是将新元素添加到第二个向量,然后在最后连接:
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());
答案 3 :(得分:1)
这样做并不是一个好主意。
您可以考虑在push_back之后需要调整矢量大小的情况。然后它需要被移动到更大的内存点,你的迭代器现在将无效。
答案 4 :(得分:0)
虽然您使用了vector作为示例,但还有其他stl容器可以推送元素而不会使迭代器失效。将元素推回到std :: list并不需要重新分配现有元素,因为它们不是连续存储的(列表包含通过指向下一个节点的链接在一起的节点),因此迭代器保持有效,因为它们内部指向的节点仍然驻留在同一地址。
答案 5 :(得分:0)
如果您需要这样做,您可以select ODRP.PAR,
SUM(CASE WHEN ODRP.TYPEID IN (1)
THEN ODRP.PLANQUANT ELSE 0 END) VALTWO
, SUM(CASE WHEN ODRP.TYPEID IN (5,6)
THEN ODRP.PLANQUANT ELSE 0 END) VALONE
from TableOne ODRP
inner join TableTwo LOC
on ODRP.LOCID = LOC.LOCID and LOC.LOCNAME like '%_USD'
group by ODRP.PAR
您可以添加的最大记录数。这将阻止向量需要调整大小,这应该可以防止崩溃