C++遍历vector<string>时越界触发访问违规,求正确实现方案
问题分析与修复
错误原因
- 语法错误:
main函数里的输出语句引号写法错误,"interpreter."应改为"interpreter.",否则会触发编译错误。 - Vector越界访问:
- 直接访问
tokens[1]前未检查vector大小,若输入指令不足2个token(比如空输入、单个单词),会直接触发越界。 - 循环中
tokens[i+1]的访问无边界检查:当i等于tokens.size()-1时,i+1超出vector有效索引范围(索引从0到size()-1),这正是你遇到0xC0000005访问违例的核心原因。
- 直接访问
修复后的代码
#include <iostream> #include <string> #include <vector> #include <sstream> using namespace std; vector<string> tokenmaker(string inst) { string out; stringstream instok(inst); vector<string> tokens; while (getline(instok, out, ' ')) { // 过滤连续空格产生的空token if (!out.empty()) { tokens.push_back(out); } } return tokens; } int main() { cout << "interpreter." << endl; bool exit = false; while (!exit) { string inst; getline(cin, inst); if (inst == "exit") { exit = true; } else { vector<string> tokens = tokenmaker(inst); // 先确保tokens长度足够访问索引1 if (tokens.size() >= 2 && tokens[1] == "print") { // 手动控制循环步长,避免越界 for (int i = 2; i < tokens.size(); ) { // 检查下一个元素是否存在且为"endl" if (i + 1 < tokens.size() && tokens[i+1] == "endl") { cout << tokens[i]; i += 2; // 跳过下一个元素 } else { cout << tokens[i] << endl; i += 1; } } } } } }
关键修复点说明
- 空token过滤:在
tokenmaker中添加空字符串判断,避免连续空格生成无效空token,减少后续越界风险。 - 前置边界检查:访问
tokens[1]前先判断tokens.size() >= 2,确保索引有效。 - 循环步长控制:取消
for循环的自动i++,根据逻辑手动调整步长(+1或+2),同时在访问i+1前确认i+1 < tokens.size(),彻底避免越界。 - 逻辑修正:原代码中
if (tokens[i+1] != "endl")逻辑写反,修复后改为判断下一个元素是endl时不输出换行,否则输出换行,逻辑更准确。
遍历Vector时检查下一个元素的正确方式
要安全检查下一个元素并跳过,需遵循两个原则:
- 访问
i+1前必须确认i+1 < tokens.size(),保证索引在有效范围内。 - 手动控制循环步长:需要跳过下一个元素时直接让
i += 2,否则i += 1,避免自动递增导致的逻辑混乱。
内容的提问来源于stack exchange,提问作者Carlos Overstreet
相关产品推荐
相关产品推荐

