C++指针练习代码抛出std::bad_alloc异常问题求助及优化建议
C++字符串单词搜索代码异常排查与优化建议
问题背景
为练习C++指针编写字符串单词搜索代码,初始版本可正常运行。为实现解耦并练习指针传参,将功能拆分到全局函数后,控制台持续抛出异常:
(C++) terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
无法运行的版本代码
#include <iostream> #include <cstring> using namespace std; int serching(char*a , const char* b, const int n); // repeating serching desginated word in the ariticle. int target(char*& a, int& b); // Let users enter a word. int main() { int timesA = 1; //recording the numbers of total words in article. int timesD = 0; //recording the numbers of designated words. const int maxlength = 10000; char a[maxlength]; cout << "Please enter the paragraph less than " << maxlength << " characters. " << endl; cin.getline(a, maxlength); size_t l = strlen(a); cout << "Total numbers of characters: " << l << endl; char* aptr = new char [l]; for(int i = 0; i < l; i++) { aptr[i] = a[i]; } int n; char* desg; int num = target(desg, n); serching(aptr, desg, num); delete[] desg; desg = 0; cout << "There are " << timesD << " designated words found in this paeagraph. " << endl; delete[] aptr; aptr = 0; return 0; } int serching(char*a , const char* b, const int n) { int num = 0; char* i = strstr(a, b); while(i != 0) { num++; i = strstr((i + n), b); } delete[] i; i = 0; return num; } int target(char*& a, int& b) { a = new char[b]; cout << "Please enter a word: " << endl; cin.getline(a, 20); b = strlen(a); delete[] a; a = 0; return b; }
可正常执行的原始版本代码
#include <iostream> #include <cstring> using namespace std; int main() { int timesA = 1; //recording the numbers of total words in article. int timesD = 0; //recording the numbers of designated words. const int maxlength = 10000; char a[maxlength]; cout << "Please enter the paragraph less than " << maxlength << " characters. " << endl; cin.getline(a, maxlength); size_t l = strlen(a); cout << "Total numbers of characters: " << l << endl; char* aptr = new char [l]; //pass into a dynamic array, for I'm practcing this. for(int i = 0; i < l; i++) { aptr[i] = a[i]; } int n; char* desg = new char[n]; cout << "Please enter a word: " << endl; cin.getline(desg, 20); n = strlen(desg); char* i = strstr(aptr, desg); // repeating serching the word in the string. while(i != 0) { timesD++; i = strstr((i + n), desg); } delete[] i; i = 0; delete[] desg; desg = 0; cout << "There are " << timesD << " designated words found in this paeagraph. " << endl; delete[] aptr; aptr = 0; return 0; }
问题排查
target函数的致命错误
- 传入的
int& b未初始化,a = new char[b];中b是随机垃圾值,可能是极大的数值,直接触发std::bad_alloc异常 - 刚分配内存就执行
delete[] a;并将a置空,导致main函数中desg变为空指针,后续serching函数调用strstr时传入空指针,引发未定义行为 cin.getline(a,20)中,a的大小是未初始化的b,若b小于20会导致缓冲区溢出
- 传入的
serching函数的错误
strstr返回的是指向原字符串内部的指针,并非通过new分配的内存,执行delete[] i;会触发未定义行为
main函数的问题
- 未接收
serching函数的返回值,timesD始终为0,输出结果错误 aptr = new char[l];只分配了l个字符空间,但原字符串a的长度是l,未预留结束符'\0'的位置,导致strlen和strstr读取越界
- 未接收
编程风格与代码优化建议
- 替换C风格字符串为std::string:完全避免手动内存管理,消除内存泄漏、越界、未初始化等问题,代码更简洁安全
- 规范函数设计:
target函数应负责创建并返回目标字符串,而非通过混乱的指针传参传递结果;函数命名修正拼写错误,如serching改为search,desginated改为designated - 初始化所有变量:避免未初始化变量导致的随机行为,比如原始版本中
int n;未初始化就用于分配内存,属于侥幸运行 - 禁止释放非动态分配的指针:
strstr返回的指针属于原字符串,无需手动释放 - 避免using namespace std;:防止全局命名空间污染,明确标注std库组件,如
std::cout、std::string - 添加输入校验:执行
cin.getline后检查输入是否成功,避免异常输入导致的错误 - 简化逻辑:原始版本中
timesA变量未被使用,可直接删除;动态复制字符串可使用strcpy(需预留结束符空间)或直接用std::string
内容的提问来源于stack exchange,提问作者Bevis000
相关产品推荐
相关产品推荐

