C++程序抛出std::bad_alloc异常报terminate called错误排查
错误原因
- 数组下标越界:你声明的
ID[15]、score[15]都是长度为15的数组,合法下标范围是0~14,但循环条件写的是i <= 15,会执行16次循环,访问ID[15]、score[15]时已经越界,属于未定义行为。 - 内存分配参数非法触发
std::bad_alloc:代码里有temp = new char[name.size()-2];,如果输入的name长度小于2,name.size()-2会变成负数,而new接收的大小参数是无符号类型,负数会被转换为极大的正整数,系统无法分配这么大的内存就会抛出std::bad_alloc异常,也就是你碰到的报错。 - 输入读取逻辑不符合需求:你要读取带空格的完整输入,但是用
cin >> name会在碰到空格时就停止读取,根本拿不到空格后的内容,后续取substr(2)的逻辑也完全不符合你“提取首字符、取空格后内容转整数”的需求。 - 字符串操作不安全:
std::string::copy不会自动在目标char数组末尾添加\0结束符,你后续调用atoi(temp)时需要传入以\0结尾的C风格字符串,这里会导致atoi读越界,结果不可预期。 - 内存泄漏:你两次
new申请的内存都没有调用delete释放,虽然小程序退出时系统会自动回收,但属于错误写法。
修复方案
- 把循环条件改为
i < 15,匹配数组长度,避免越界。 - 改用
getline读取完整的带空格的用户输入,正确拆分首字符和空格后的数字部分。 - 不需要额外申请char数组,直接用
std::string的方法操作即可,避免内存分配错误和泄漏。 - 增加输入合法性校验,避免非法输入导致程序崩溃。
修复后的完整代码如下:
#include <iostream> #include <string> #include <cctype> using namespace std; int main() { char ID[15]; int score[15]; int i; cout<< "Hello there!:\n"; // 忽略缓冲区残留的换行符,避免getline第一次读取为空 cin.ignore(); for (i = 0; i < 15; i++) { cout<< "Please enter ID and score separated by space:"; string line; getline(cin, line); if (line.empty()) { cout << "Input can not be empty, try again\n"; i--; continue; } // 提取首字符作为ID ID[i] = line[0]; // 查找第一个空格的位置 size_t space_pos = line.find(' '); if (space_pos == string::npos || space_pos == line.size()-1) { cout << "Invalid input, please enter in format [ID char] [score number]\n"; i--; continue; } // 提取空格后内容转整数 string score_str = line.substr(space_pos + 1); // 简单校验分数是否为合法整数 bool is_valid_num = true; for (char c : score_str) { if (!isdigit(c)) { is_valid_num = false; break; } } if (!is_valid_num) { cout << "Score must be integer, try again\n"; i--; continue; } score[i] = stoi(score_str); } cout << endl; cout << "ID" << " " << "Score" << endl; for (i = 0; i < 15; i++) { cout << ID[i] << " "<< score[i] << endl; } return 0; }
内容的提问来源于stack exchange,提问作者peq42
相关产品推荐
相关产品推荐

