为何vector迭代器it2在循环内显示乱值而非正常数值?
问题描述
尝试用C++的vector实现一维数组前缀和并学习迭代器使用,编写了如下代码:
vector<int> nums; nums.push_back(1); nums.push_back(2); nums.push_back(3); vector<int> res; res.push_back(nums.front()); vector<int>::iterator it = nums.begin(); vector<int>::iterator it2 = res.begin(); ++it; cout << "it2 -> " << *it2 << endl; cout << "it + it2 " << *it + *it2 << endl; while(it != nums.end()) { res.push_back(*it + *it2); cout << "it : " << *it << endl; cout << "it2 : " << *it2 << endl; cout << "pushed " << (*it + *it2) << " "; it++; it2++; } it = nums.begin(); while(it != nums.end()) { cout << *it << " "; ++ it; } cout << endl; it2 = res.begin(); while(it2 != res.end()) { cout << *it2 << " "; ++it2; } cout << endl;
运行后输出:
it2 -> 1 it + it2 3 it : 2 it2 : 17858448 pushed 17858450 it : 3 it2 : 17825984 pushed 17825987 1 2 3 1 3 17825987
疑惑点:*it2在循环外取值正常,但进入循环后显示乱值,需要明确代码失效的原因。
失效原因
核心问题是vector的迭代器失效。
vector底层采用连续内存存储,默认初始容量很小(通常为0或1)。当调用res.push_back()时,如果当前容量不足以容纳新元素,vector会触发扩容机制:
- 分配一块更大的新内存空间
- 将原内存中的元素拷贝到新空间
- 释放原内存空间
你的代码中,初始化res时只push了一个元素,此时res的容量可能仅为1。第一次进入循环执行res.push_back()时,容量不足触发扩容,原内存被释放。而你之前保存的it2迭代器指向的是原内存地址,这块内存已不属于res,变成野指针,解引用*it2就会读取到随机垃圾值。
修复方案
有两种常用解决思路:
方法1:提前预留足够容量
在初始化res后,调用res.reserve(nums.size()),提前给res分配足够容纳所有前缀和的内存,后续push_back不会触发扩容,迭代器就不会失效。
修正后的代码片段:
vector<int> res; res.reserve(nums.size()); // 提前预留容量 res.push_back(nums.front()); vector<int>::iterator it = nums.begin(); vector<int>::iterator it2 = res.begin(); // 后续代码不变
方法2:避免使用失效的迭代器
每次循环中,不依赖之前保存的it2,而是通过res的当前末尾元素计算(比如用res.back()),或者通过索引访问。比如把循环内逻辑改成:
while(it != nums.end()) { int next_sum = *it + res.back(); res.push_back(next_sum); cout << "it : " << *it << endl; cout << "last sum : " << res[res.size()-2] << endl; // 取上一个前缀和 cout << "pushed " << next_sum << " "; it++; }
这种方法无需担心迭代器失效,因为每次都是直接访问当前有效的内存位置。
内容的提问来源于stack exchange,提问作者Anant
相关产品推荐
相关产品推荐

