C++使用vector开发电影列表时调用展示函数触发std::out_of_range异常
报错根因与修复方案
核心错误定位
- ShowMovies函数循环逻辑完全颠倒,是触发out_of_range的直接原因
原循环判断条件为movieList.size() > 1,该条件仅判断容器长度是否大于1,完全没有限制循环变量i的取值上限,循环会无限执行、i持续自增,当i的数值超过容器最大有效索引时,调用带边界检查的.at()方法就会抛出std::out_of_range异常。
实际执行流程举例:初始化3部电影,若用户输入2删除对应影片,剩余容器长度为2。循环启动后,i依次取0、1完成正常打印后,i自增为2,此时循环判断size()=2 > 1仍成立,代码会尝试访问索引为2的元素——长度为2的vector最大有效索引为1,直接触发越界报错。
除此之外该条件还有逻辑漏洞:如果删除操作后容器仅剩1个元素,size() >1判断直接不成立,循环一次都不会执行,无法打印剩余的唯一影片。 - DeleteMovie函数缺少入参边界校验,存在隐藏崩溃风险
原实现直接将用户传入的序号减1作为偏移量删除元素,若用户输入的序号小于1、大于列表总长度,erase操作会落在容器内存范围外,触发未定义行为甚至直接程序崩溃。 - 冗余无效声明
全局变量std::vector <int>::iterator it;在全流程中没有被使用,属于无意义的冗余代码。 - 隐含头文件缺失风险
代码中使用了std::string类型但未显式包含<string>头文件,部分宽松编译器可能允许通过编译,换用严格编译规则的环境会直接报编译错误。
修正后的可运行代码
#include <iostream> #include <vector> #include <string> // 补全string类型所需头文件 std::vector <std::string> movieList; // 移除无用的全局iterator声明 void AddMovie(std::string movie) { movieList.push_back(movie); } void DeleteMovie(int inputIndex) { int listLen = static_cast<int>(movieList.size()); // 增加入参边界校验 if (inputIndex < 1 || inputIndex > listLen) { std::cout << "输入序号超出电影列表范围" << std::endl; return; } movieList.erase(movieList.begin() + inputIndex - 1); } void ShowMovies() { // 循环条件修正为判断i是否在有效索引范围内 int listLen = static_cast<int>(movieList.size()); for (int i = 0; i < listLen; i++) { std::cout << movieList.at(i) << std::endl; } } int main() { int input{ 0 }; movieList.push_back("Inception"); movieList.push_back("Peter Pan"); movieList.push_back("Jaws"); std::cout << "Delete movie: "; std::cin >> input; DeleteMovie(input); ShowMovies(); }
内容的提问来源于stack exchange,提问作者AdamKxZ
相关产品推荐
相关产品推荐

